• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Поставщик календаря
2@jd:body
3
4<div id="qv-wrapper">
5<div id="qv">
6    <h2>Содержание документа</h2>
7    <ol>
8  <li><a href="#overview">Основы</a></li>
9  <li><a href="#manifest">Разрешения пользователей</a></li>
10  <li><a href="#calendar">Таблица календарей</a>
11<ol>
12      <li><a href="#query">Запрос календаря</a></li>
13      <li><a href="#modify-calendar">Изменение календаря</a></li>
14      <li><a href="#insert-calendar">Вставка календаря</a></li>
15    </ol>
16  </li>
17  <li><a href="#events">Таблица событий</a>
18<ol>
19      <li><a href="#add-event">Добавление событий</a></li>
20      <li><a href="#update-event">Обновление событий</a></li>
21      <li><a href="#delete-event">Удаление событий</a></li>
22    </ol>
23  </li>
24  <li><a href="#attendees">Таблица участников</a>
25<ol>
26      <li><a href="#add-attendees">Добавление участников</a></li>
27    </ol>
28  </li>
29  <li><a href="#reminders">Таблица напоминаний</a>
30<ol>
31      <li><a href="#add-reminders">Добавление напоминаний</a></li>
32    </ol>
33  </li>
34  <li><a href="#instances">Таблица экземпляров</a>
35  <ol>
36      <li><a href="#query-instances">Запрос таблицы экземпляров</a></li>
37  </ol></li>
38  <li><a href="#intents">Намерения календаря</a>
39  <ol>
40      <li><a href="#intent-insert">Использование намерения для вставки события</a></li>
41      <li><a href="#intent-edit">Использование намерения для редактирования события</a></li>
42      <li><a href="#intent-view">Использование намерения для просмотра данных календаря</a></li>
43    </ol>
44  </li>
45
46  <li><a href="#sync-adapter">Адаптеры синхронизации</a></li>
47</ol>
48
49    <h2>Ключевые классы</h2>
50    <ol>
51      <li>{@link android.provider.CalendarContract.Calendars}</li>
52      <li>{@link android.provider.CalendarContract.Events}</li>
53      <li>{@link android.provider.CalendarContract.Attendees}</li>
54      <li>{@link android.provider.CalendarContract.Reminders}</li>
55    </ol>
56</div>
57</div>
58
59<p>Поставщик календаря представляет собой репозиторий для событий календаря пользователя. API
60поставщика календаря позволяет запрашивать, вставлять, обновлять и удалять календари,
61события, участников, напоминания и т. д.</p>
62
63
64<p>API поставщика календаря может использоваться как приложениями, так и адаптерами синхронизации. Правила
65зависят от типа программы, которая выполняет вызовы. В этой статье
66главным образом рассматривается использование API поставщика календаря в качестве приложения. Сведения о различиях
67между адаптерами синхронизации представлены в разделе
68<a href="#sync-adapter">Адаптеры синхронизации</a>.</p>
69
70
71<p>Обычно, чтобы считать или записать данные календаря, в манифесте приложения
72должны быть включены надлежащие разрешения, которые описываются в разделе <a href="#manifest">Разрешения
73пользователей</a>. Чтобы упростить выполнение часто используемых операций, в поставщике
74календаря предусмотрен набор намерений, как описано в разделе <a href="#intents">Намерения
75календаря</a>. Эти намерения позволяют пользователям переходить в приложение календаря для вставки, просмотра
76и редактирования событий. После взаимодействия пользователя с календарем он возвращается
77в исходное приложение. Поэтому вашему приложению не нужно запрашивать разрешения,
78а также предоставлять пользовательский интерфейс для просмотра или создания событий.</p>
79
80<h2 id="overview">Основы</h2>
81
82<p><a href="{@docRoot}guide/topics/providers/content-providers.html">Поставщики контента</a> хранят в себе данные и предоставляют к ним доступ
83для приложений. Поставщики контента, предлагаемые платформой Android (включая поставщик календаря) обычно представляют данные в виде набора таблиц, в основе
84которых лежит модель реляционной базы данных. Каждая строка в такой таблице представляет собой запись, а каждый столбец — данные
85определенного типа и значения. Благодаря API поставщика календаря приложения
86и адаптеры синхронизации получают доступ на чтение/запись к таблицам в базе данных, в которых
87представлены данные календаря пользователя.</p>
88
89<p>Каждый поставщик календаря предоставляет общедоступный URI (упакованный в объект
90{@link android.net.Uri}),
91который служит уникальным идентификатором своего набора данных.  Поставщик контента, который управляет
92несколькими наборами данных (несколькими таблицами), предоставляет отдельный URI для каждого набора.  Все
93URI поставщиков начинаются со строки content://.  Она
94определяет данные, которые находятся под управлением поставщика контента. Поставщик календаря
95задает константы для URI каждого из своих классов (таблиц). Такие
96URI имеют формат <code><em>&lt;class&gt;</em>.CONTENT_URI</code>. Например,
97{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.</p>
98
99<p>На рисунке 1 изображено графическое представление модели данных поставщика календаря. На нем представлены
100основные таблицы и поля, которые связывают их друг с другом.</p>
101
102<img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model" />
103<p class="img-caption"><strong>Рисунок 1.</strong> Модель данных поставщика календаря.</p>
104
105<p>У пользователя может быть несколько календарей, причем они могут быть связаны с аккаунтами разных типов (Google Календарь, Exchange и т. д.).</p>
106
107<p>Класс {@link android.provider.CalendarContract} определяет модель данных календаря и информацию, относящуюся к событиям. Эти данные хранятся в различных таблицах, указанных ниже.</p>
108
109<table>
110  <tr>
111    <th>Таблица (класс)</th>
112    <th>Описание</th>
113  </tr>
114  <tr>
115    <td><p>{@link android.provider.CalendarContract.Calendars}</p></td>
116
117    <td>В этой таблице находится
118информация о календарях. В каждой строке этой таблицы представлены сведения
119об отдельном календаре, например, его название, цвет, информация о синхронизации и т. д.</td>
120  </tr>
121  <tr>
122    <td>{@link android.provider.CalendarContract.Events}</td>
123
124    <td>В этой таблице находится
125информация о событиях. В каждой строке этой таблицы содержится информация об отдельном
126событии &mdash;например, заголовок события, место проведения, время начала, время
127завершения и т. д. Событие может быть однократным или повторяющимся. Сведения об участниках,
128напоминаниях и расширенные свойства хранятся в отдельных таблицах.
129В каждой из них имеется целочисленная переменная {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID},
130которая ссылается на объект {@link android.provider.BaseColumns#_ID} в таблице событий.</td>
131
132  </tr>
133  <tr>
134    <td>{@link android.provider.CalendarContract.Instances}</td>
135
136    <td>В этой таблице содержатся данные о времени
137начала и окончания каждого повторения события. В каждой строке этой таблицы
138представлено одно повторение события. Однократные события сопоставляются с повторениями
139один к одному. Для повторяющихся событий автоматически создаются несколько строк,
140которые соответствуют нескольким повторениям события.</td>
141  </tr>
142  <tr>
143    <td>{@link android.provider.CalendarContract.Attendees}</td>
144
145    <td>В этой таблице находится
146информация об участниках (гостях). В каждой строке этой таблицы указан один
147гость. В ней указываются тип гостя и информация о том,
148посетит ли он событие.</td>
149  </tr>
150  <tr>
151    <td>{@link android.provider.CalendarContract.Reminders}</td>
152
153    <td>В этой таблице находятся
154данные уведомлений или оповещений. В каждой строке этой таблицы указано одно уведомление или оповещение. Для одного
155события можно создать несколько напоминаний. Максимальное количество таких напоминаний для события
156задается с помощью
157целочисленной переменной {@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS},
158значение которой задает адаптер синхронизации, владеющий
159указанным календарем. Напоминания задаются в минутах до начала события и
160имеют метод, который определяет порядок уведомления пользователя.</td>
161  </tr>
162
163</table>
164
165<p>API поставщика календаря обеспечивает достаточную гибкость и эффективность. В то же время
166важно предоставить интерфейс, который будет удобным для пользователя,
167и обеспечить защиту целостности календаря и его данных. Поэтому существует
168ряд моментов, которые следует учитывать при использовании этого API.</p>
169
170<ul>
171
172<li><strong>Вставка, обновление и просмотр событий календаря.</strong> Чтобы вставить, изменить и считать события напрямую из поставщика календаря, требуются соответствующие <a href="#manifest">разрешения</a>. Однако, если вы не планируете создавать полнофункциональное приложение календаря или адаптер синхронизации, запрашивать такие разрешения не обязательно. Вместо этого можно использовать намерения, поддерживаемые приложением «Календарь» Android, для обработки операций чтения и записи в этом приложении. При использовании намерений ваше приложение отправляет пользователям приложение «Календарь» для выполнения требуемой операции
173в предварительно заполненной форме. По завершении они возвращаются в приложение.
174Реализовав в вашем приложении возможность выполнения часто используемых операций через приложение «Календарь»,
175вы обеспечиваете для пользователей единообразный и функциональный пользовательский интерфейс. Мы рекомендуем использовать
176именно такой подход. Дополнительные сведения представлены в разделе <a href="#intents">Намерения
177календаря</a>.</p>
178
179
180<li><strong>Адаптеры синхронизации.</strong> Адаптер синхронизации синхронизирует данные календаря
181на устройстве пользователя с данными на сервере или в другом источнике данных. В таблицах
182{@link android.provider.CalendarContract.Calendars} и
183{@link android.provider.CalendarContract.Events} имеются
184столбцы, зарезервированные для адаптеров синхронизации.
185Ни поставщик, ни приложения не должны изменять их. Фактически они скрыты
186до тех пор, пока адаптер синхронизации не начнет использовать их. Дополнительные сведения об
187адаптерах синхронизации представлены в разделе <a href="#sync-adapter">Адаптеры синхронизации</a>.</li>
188
189</ul>
190
191
192<h2 id="manifest">Разрешения пользователей</h2>
193
194<p>Чтобы считать данные календаря, в файл манифеста приложения необходимо включить разрешение {@link
195android.Manifest.permission#READ_CALENDAR}. Также в него
196следует включить разрешение {@link android.Manifest.permission#WRITE_CALENDAR}
197для удаления, вставки или обновления данных календаря:</p>
198
199<pre>
200&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
201&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;...&gt;
202    &lt;uses-sdk android:minSdkVersion=&quot;14&quot; /&gt;
203    &lt;uses-permission android:name=&quot;android.permission.READ_CALENDAR&quot; /&gt;
204    &lt;uses-permission android:name=&quot;android.permission.WRITE_CALENDAR&quot; /&gt;
205    ...
206&lt;/manifest&gt;
207</pre>
208
209
210<h2 id="calendar">Таблица календарей</h2>
211
212<p>В таблице {@link android.provider.CalendarContract.Calendars} содержатся подробные сведения
213о каждом отдельном календаре. Выполнять запись в указанные ниже столбцы
214этой таблицы могут и приложение, и <a href="#sync-adapter">адаптер синхронизации</a>.
215Полный список поддерживаемых полей представлен в справке по классу
216{@link android.provider.CalendarContract.Calendars}.</p>
217<table>
218  <tr>
219    <th>Константа</th>
220    <th>Описание</th>
221  </tr>
222  <tr>
223    <td>{@link android.provider.CalendarContract.Calendars#NAME}</td>
224    <td>Название календаря.</td>
225  </tr>
226  <tr>
227    <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td>
228    <td>Название этого календаря, которое отображается для пользователя.</td>
229  </tr>
230  <tr>
231    <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td>
232
233    <td>Логическое значение, обозначающее, выбран ли календарь для отображения. Значение
234«0» указывает на то, что события, связанные с
235этим календарем, не отображаются.  Значение «1» указывает на то, что события, связанные с
236этим календарем, отображаются. Это значение влияет на создание строк в таблице {@link
237android.provider.CalendarContract.Instances}.</td>
238
239
240  </tr>
241  <tr>
242    <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td>
243
244    <td>Логическое значение, обозначающее, следует ли синхронизировать календарь и хранить имеющиеся в нем события
245на устройстве. Значение «0» указывает, что не следует синхронизировать этот календарь или
246хранить имеющиеся в нем события на устройстве.  Значение «1» указывает, что этот календарь следует синхронизировать и
247хранить имеющиеся в нем события на устройстве.</td>
248  </tr>
249</table>
250
251<h3 id="query">Запрос календаря</h3>
252
253<p>Ниже представлен пример того, как получить календари, которыми
254владеет определенный пользователь. Для простоты демонстрации операция запроса в этом примере находится в
255потоке пользовательского интерфейса («основной поток»). На практике это следует делать в асинхронном
256потоке, а не в основном. Дополнительные сведения представлены в статье
257<a href="{@docRoot}guide/components/loaders.html">Загрузчики</a>. Если же вы не только
258считываете данные, но и вносите в них изменения, обратитесь к справке по классу {@link android.content.AsyncQueryHandler}.
259</p>
260
261
262<pre>
263// Projection array. Creating indices for this array instead of doing
264// dynamic lookups improves performance.
265public static final String[] EVENT_PROJECTION = new String[] {
266    Calendars._ID,                           // 0
267    Calendars.ACCOUNT_NAME,                  // 1
268    Calendars.CALENDAR_DISPLAY_NAME,         // 2
269    Calendars.OWNER_ACCOUNT                  // 3
270};
271
272// The indices for the projection array above.
273private static final int PROJECTION_ID_INDEX = 0;
274private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
275private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
276private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;</pre>
277
278
279<div class="sidebox-wrapper"> <div class="sidebox"> <h3>Зачем необходимо указывать параметр
280ACCOUNT_TYPE?</h3> <p>При создании запроса {@link
281android.provider.CalendarContract.Calendars#ACCOUNT_NAME
282Calendars.ACCOUNT_NAME} необходимо также
283указать
284{@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}. Это необходимо сделать ввиду того, что указанный аккаунт
285считается уникальным только тогда, когда для него указаны и параметр <code>ACCOUNT_NAME</code>, и параметр
286<code>ACCOUNT_TYPE</code>. Параметр <code>ACCOUNT_TYPE</code> в строке обозначает
287структуру проверки подлинности аккаунта, которая использовалась при регистрации аккаунта с помощью
288{@link android.accounts.AccountManager}. Существует также особый тип аккаунтов, называемый {@link
289android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}. Он используется для календарей,
290которые не связаны с аккаунтом устройства. Аккаунты {@link
291android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} не
292синхронизируются.</p> </div> </div>
293
294
295<p> В следующей части примера создается запрос. С помощью выбора определяются
296критерии для запроса. В этом примере выполняется поиск
297календарей со следующими значениями параметров: <code>ACCOUNT_NAME</code>
298— sampleuser@google.com, <code>ACCOUNT_TYPE</code>
299com.google и <code>OWNER_ACCOUNT</code>
300 — sampleuser@google.com. Для просмотра всех просмотренных
301пользователем календарей, а не только имеющихся у него, не указывайте параметр <code>OWNER_ACCOUNT</code>.
302Запрос возвращает объект {@link android.database.Cursor},
303который можно использовать для перебора результатов, возвращенных запросом к базе
304данных. Дополнительные сведения об использовании запросов в поставщиках контента
305представлены в статье <a href="{@docRoot}guide/topics/providers/content-providers.html">Поставщики контента</a>.</p>
306
307
308<pre>// Run query
309Cursor cur = null;
310ContentResolver cr = getContentResolver();
311Uri uri = Calendars.CONTENT_URI;
312String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
313                        + Calendars.ACCOUNT_TYPE + " = ?) AND ("
314                        + Calendars.OWNER_ACCOUNT + " = ?))";
315String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google",
316        "sampleuser@gmail.com"};
317// Submit the query and get a Cursor object back.
318cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre>
319
320<p>В следующем разделе кода выполняется пошаговый обзор набора результатов с помощью курсора. В нем
321используются константы, которые были заданы в начале примера, для получения значений
322для каждого из полей.</p>
323
324<pre>// Use the cursor to step through the returned records
325while (cur.moveToNext()) {
326    long calID = 0;
327    String displayName = null;
328    String accountName = null;
329    String ownerName = null;
330
331    // Get the field values
332    calID = cur.getLong(PROJECTION_ID_INDEX);
333    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
334    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
335    ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
336
337    // Do something with the values...
338
339   ...
340}
341</pre>
342
343<h3 id="modify-calendar">Изменение календаря</h3>
344
345<p>Чтобы обновить календарь, можно указать {@link
346android.provider.BaseColumns#_ID} календаря: либо в виде идентификатора,
347добавленного к URI
348
349({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}),
350либо в качестве первого элемента выделения. Выделение
351должно начинаться с <code>&quot;_id=?&quot;</code>, а первым аргументом
352<code>selectionArg</code> должен быть {@link
353android.provider.BaseColumns#_ID} календаря.
354Также для выполнения обновлений можно закодировать идентификатор в URI. В этом примере для
355изменения отображаемого имени календаря используется
356подход
357({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}):</p>
358
359<pre>private static final String DEBUG_TAG = "MyActivity";
360...
361long calID = 2;
362ContentValues values = new ContentValues();
363// The new display name for the calendar
364values.put(Calendars.CALENDAR_DISPLAY_NAME, &quot;Trevor's Calendar&quot;);
365Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
366int rows = getContentResolver().update(updateUri, values, null, null);
367Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);</pre>
368
369<h3 id="insert-calendar">Вставка календаря</h2>
370
371<p>Для управления календарями в основном используются адаптеры синхронизации, поэтому
372новые календари следует вставлять исключительно как адаптер синхронизации. По большей части
373приложения могут вносить в календари только поверхностные изменения, такие как изменение отображаемого имени. Если
374приложению требуется создать локальный календарь, это можно сделать путем
375вставки календаря в виде адаптера синхронизации с помощью параметра {@link
376android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} типа {@link
377android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}.
378{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}
379представляет собой особый тип аккаунтов для календарей, которые не связаны
380с аккаунтом устройства. Календари этого типа не синхронизируются с сервером. Дополнительные сведения
381об адаптерах синхронизации представлены в статье <a href="#sync-adapter">Адаптеры синхронизации</a>.</p>
382
383<h2 id="events">Таблица событий</h2>
384
385<p>В таблице {@link android.provider.CalendarContract.Events} содержатся подробные сведения
386о каждом отдельном событии. Чтобы получить возможность добавлять, обновлять или удалять события,
387в <a href="#manifest">файл манифеста</a>
388приложения необходимо включить разрешение {@link android.Manifest.permission#WRITE_CALENDAR}.</p>
389
390<p>Выполнять запись в указанные ниже столбцы этой таблицы могут и приложение, и
391адаптер синхронизации. Полный список поддерживаемых полей представлен в справке по классу {@link
392android.provider.CalendarContract.Events}.</p>
393
394<table>
395  <tr>
396    <th>Константа</th>
397    <th>Описание</th>
398  </tr>
399  <tr>
400    <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td>
401    <td>{@link android.provider.BaseColumns#_ID} календаря, к которому принадлежит событие.</td>
402  </tr>
403  <tr>
404    <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td>
405    <td>Адрес эл. почты организатора (владельца) события.</td>
406  </tr>
407  <tr>
408    <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td>
409    <td>Название события.</td>
410  </tr>
411  <tr>
412    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td>
413    <td>Место проведения. </td>
414  </tr>
415  <tr>
416    <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td>
417    <td>Описание события.</td>
418  </tr>
419  <tr>
420    <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td>
421    <td>Время начала события по UTC (в миллисекундах) от точки отсчета. </td>
422  </tr>
423  <tr>
424    <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td>
425    <td>Время окончания события по UTC (в миллисекундах) от точки отсчета. </td>
426  </tr>
427  <tr>
428    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td>
429    <td>Часовой пояс события.</td>
430  </tr>
431  <tr>
432    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td>
433    <td>Часовой пояс для времени окончания события.</td>
434  </tr>
435  <tr>
436    <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td>
437
438    <td>Продолжительность события в формате <a href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a>.
439Например, значение <code>&quot;PT1H&quot;</code> обозначает, что событие
440должно длиться один час, а значение <code>&quot;P2W&quot;</code> указывает на продолжительность
441в 2 недели. </td>
442
443
444  </tr>
445  <tr>
446    <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td>
447
448    <td>Значение «1» обозначает, что это событие занимает весь день по
449местному часовому поясу. Значение «0» указывает на то, что это регулярное событие, которое может начаться
450и завершиться в любое время в течение дня.</td>
451
452
453  </tr>
454
455
456  <tr>
457    <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td>
458
459    <td>Правило повторения для формата события. Например,
460<code>&quot;FREQ=WEEKLY;COUNT=10;WKST=SU&quot;</code>. С другими
461примерами можно ознакомиться <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">здесь</a>.</td>
462
463  </tr>
464
465  <tr>
466    <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td>
467    <td>Даты повторения события.
468Обычно {@link android.provider.CalendarContract.EventsColumns#RDATE}
469используется вместе с {@link android.provider.CalendarContract.EventsColumns#RRULE}
470для определения агрегированного набора
471повторяющихся событий. Дополнительные сведения представлены в <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">спецификации RFC5545</a>.</td>
472</tr>
473
474  <tr>
475    <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td>
476
477    <td>Если событие считается как занятое или как свободное время,
478 доступное для планирования. </td>
479
480  </tr>
481  <tr>
482    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td>
483    <td>Указывает, могут ли гости вносить изменения в событие. </td>
484  </tr>
485  <tr>
486    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td>
487    <td>Указывает, могут ли гости приглашать других гостей. </td>
488  </tr>
489  <tr>
490    <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td>
491    <td>Указывает, могут ли гости просматривать список участников.</td>
492  </tr>
493</table>
494
495<h3 id="add-event">Добавление событий</h3>
496
497<p>Когда ваше приложение вставляет новое событие, мы рекомендуем использовать намерение
498{@link android.content.Intent#ACTION_INSERT INSERT}, как описано в разделе <a href="#intent-insert">Использование намерения для вставки события</a>. Однако при
499необходимости вы можете вставлять события напрямую. В этом разделе как раз описывается то, как это
500сделать.</p>
501
502
503<p>Ниже указаны правила, которыми следует руководствоваться для вставки нового события. </p>
504<ul>
505
506  <li>Необходимо указать {@link
507android.provider.CalendarContract.EventsColumns#CALENDAR_ID} и {@link
508android.provider.CalendarContract.EventsColumns#DTSTART}.</li>
509
510<li>Необходимо указать {@link
511android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}. Чтобы получить список
512установленных в системе идентификаторов часовых поясов, воспользуйтесь методом {@link
513java.util.TimeZone#getAvailableIDs()}. Обратите внимание, что это правило не применяется при
514вставке события с помощью намерения {@link
515android.content.Intent#ACTION_INSERT INSERT}, как описано в разделе <a href="#intent-insert">Использование намерения для вставки события</a>, &mdash; в этом
516случае используется часовой пояс по умолчанию.</li>
517
518  <li>Для однократных событий необходимо указать {@link
519android.provider.CalendarContract.EventsColumns#DTEND}. </li>
520
521
522  <li>Для повторяющихся событий необходимо указать {@link
523android.provider.CalendarContract.EventsColumns#DURATION} в дополнение к {@link
524android.provider.CalendarContract.EventsColumns#RRULE} или {@link
525android.provider.CalendarContract.EventsColumns#RDATE}. Обратите внимание, что это правило не применяется при
526вставке события с помощью намерения {@link
527android.content.Intent#ACTION_INSERT INSERT}, как описано в разделе <a href="#intent-insert">Использование намерения для вставки события</a>, &mdash; в этом
528случае можно использовать {@link
529android.provider.CalendarContract.EventsColumns#RRULE} в сочетании с {@link android.provider.CalendarContract.EventsColumns#DTSTART} и {@link android.provider.CalendarContract.EventsColumns#DTEND}; кроме того, приложение «Календарь»
530 автоматически преобразует указанный период в продолжительность.</li>
531
532</ul>
533
534<p>Ниже представлен пример вставки события. Для простоты все это выполняется в потоке
535пользовательского интерфейса. На практике же все вставки и обновления следует выполнять в
536асинхронном потоке, чтобы переместить операцию в фоновый поток. Дополнительные сведения представлены в справке по
537{@link android.content.AsyncQueryHandler}.</p>
538
539
540<pre>
541long calID = 3;
542long startMillis = 0;
543long endMillis = 0;
544Calendar beginTime = Calendar.getInstance();
545beginTime.set(2012, 9, 14, 7, 30);
546startMillis = beginTime.getTimeInMillis();
547Calendar endTime = Calendar.getInstance();
548endTime.set(2012, 9, 14, 8, 45);
549endMillis = endTime.getTimeInMillis();
550...
551
552ContentResolver cr = getContentResolver();
553ContentValues values = new ContentValues();
554values.put(Events.DTSTART, startMillis);
555values.put(Events.DTEND, endMillis);
556values.put(Events.TITLE, &quot;Jazzercise&quot;);
557values.put(Events.DESCRIPTION, &quot;Group workout&quot;);
558values.put(Events.CALENDAR_ID, calID);
559values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
560Uri uri = cr.insert(Events.CONTENT_URI, values);
561
562// get the event ID that is the last element in the Uri
563long eventID = Long.parseLong(uri.getLastPathSegment());
564//
565// ... do something with event ID
566//
567//</pre>
568
569<p class="note"><strong>Примечание.</strong> Ниже демонстрируется, как в примере кода выполняется захват
570идентификатора события после создания этого события. Это самый простой способ получить идентификатор события. Зачастую
571идентификатор события необходим для выполнения других действий с календарем &mdash; например, для добавления участников или
572напоминаний о событии.</p>
573
574
575<h3 id="update-event">Обновление событий</h3>
576
577<p>Когда ваше приложение хочет предоставить пользователю возможность изменить событие, мы рекомендуем использовать намерение
578{@link android.content.Intent#ACTION_EDIT EDIT}, как описано в разделе
579<a href="#intent-edit">Использование намерения для вставки события</a>.
580Однако при необходимости вы можете редактировать события напрямую. Чтобы обновить
581событие, можно указать
582<code>_ID</code> события: либо в виде идентификатора, добавленного к URI({@link
583android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}),
584либо в качестве первого элемента выделения. Выделение
585должно начинаться с <code>&quot;_id=?&quot;</code>, а первым аргументом
586<code>selectionArg</code> должен быть <code>_ID</code> события. Также можно обновлять
587выделения без идентификаторов. Ниже представлен пример обновления
588события. Это пример изменения названия события с помощью
589метода
590{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}:</p>
591
592
593<pre>private static final String DEBUG_TAG = "MyActivity";
594...
595long eventID = 188;
596...
597ContentResolver cr = getContentResolver();
598ContentValues values = new ContentValues();
599Uri updateUri = null;
600// The new title for the event
601values.put(Events.TITLE, &quot;Kickboxing&quot;);
602updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
603int rows = getContentResolver().update(updateUri, values, null, null);
604Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);  </pre>
605
606<h3 id="delete-event">Удаление событий</h3>
607
608<p>Удалить событие можно по его {@link
609android.provider.BaseColumns#_ID}, который добавлен в качестве идентификатора к URI, или с помощью
610стандартного выделения. В случае использования добавленного идентификатора невозможно также выполнить и выделение.
611Существует две версии операции удаления: для приложения и для адаптера синхронизации. При удалении
612для приложения в столбце <em>deleted</em> устанавливается значение «1». Этот флаг
613сообщает адаптеру синхронизации о том, что строка была удалена и информацию об удалении следует
614передать серверу. При удалении для адаптера синхронизации событие удаляется из
615базы данных вместе со всеми связанными с ним данными. Ниже представлен пример удаления
616события для приложения по его {@link android.provider.BaseColumns#_ID}.</p>
617
618
619<pre>private static final String DEBUG_TAG = "MyActivity";
620...
621long eventID = 201;
622...
623ContentResolver cr = getContentResolver();
624ContentValues values = new ContentValues();
625Uri deleteUri = null;
626deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
627int rows = getContentResolver().delete(deleteUri, null, null);
628Log.i(DEBUG_TAG, &quot;Rows deleted: &quot; + rows);
629</pre>
630
631<h2 id="attendees">Таблица участников</h2>
632
633<p>В каждой строке таблицы {@link android.provider.CalendarContract.Attendees}
634указан один участник или гость события. При вызове метода
635{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()}
636возвращается список участников для события
637с заданным {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}.
638Этот {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}
639должен соответствовать {@link
640android.provider.BaseColumns#_ID} определенного события.</p>
641
642<p>В таблице ниже указаны
643поля, доступные для записи. При вставке нового участника необходимо указать все эти поля, кроме
644<code>ATTENDEE_NAME</code>.
645</p>
646
647
648<table>
649  <tr>
650    <th>Константа</th>
651    <th>Описание</th>
652  </tr>
653  <tr>
654    <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td>
655    <td>Идентификатор события.</td>
656  </tr>
657  <tr>
658    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td>
659    <td>Имя участника.</td>
660  </tr>
661  <tr>
662    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td>
663    <td>Адрес эл. почты участника.</td>
664  </tr>
665  <tr>
666    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td>
667    <td><p>Связь участника с событием. Одно из следующего:</p>
668      <ul>
669        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li>
670        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li>
671        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li>
672        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li>
673        <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li>
674    </ul>
675    </td>
676  </tr>
677  <tr>
678    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td>
679    <td><p>Тип участника. Одно из следующего: </p>
680      <ul>
681        <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li>
682        <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li>
683    </ul></td>
684  </tr>
685  <tr>
686    <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td>
687    <td><p>Статус посещения события участником. Одно из следующего:</p>
688      <ul>
689        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li>
690        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li>
691        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li>
692        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li>
693        <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li>
694    </ul></td>
695  </tr>
696</table>
697
698<h3 id="add-attendees">Добавление участников</h3>
699
700<p>Ниже представлен пример добавления одного участника события. Обратите внимание, что нужно в обязательном порядке
701указать
702{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}.</p>
703
704<pre>
705long eventID = 202;
706...
707ContentResolver cr = getContentResolver();
708ContentValues values = new ContentValues();
709values.put(Attendees.ATTENDEE_NAME, &quot;Trevor&quot;);
710values.put(Attendees.ATTENDEE_EMAIL, &quot;trevor@example.com&quot;);
711values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
712values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
713values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
714values.put(Attendees.EVENT_ID, eventID);
715Uri uri = cr.insert(Attendees.CONTENT_URI, values);
716</pre>
717
718<h2 id="reminders">Таблица напоминаний</h2>
719
720<p>В каждой строке таблицы {@link android.provider.CalendarContract.Reminders}
721указано одно напоминание о событии. При вызове метода
722{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()}возвращается список напоминаний для события
723с заданным
724{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}.</p>
725
726
727<p>В таблице ниже указаны поля, доступные для записи. При вставке нового
728напоминания необходимо указать все эти поля. Обратите внимание, что адаптеры синхронизации задают
729типы напоминаний, которые они поддерживают, в таблице {@link
730android.provider.CalendarContract.Calendars}. Подробные сведения см.
731в справке по
732{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS}.</p>
733
734
735<table>
736  <tr>
737    <th>Константа</th>
738    <th>Описание</th>
739  </tr>
740  <tr>
741    <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td>
742    <td>Идентификатор события.</td>
743  </tr>
744  <tr>
745    <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td>
746    <td>Время срабатывания уведомления (в минутах) до начала события.</td>
747  </tr>
748  <tr>
749    <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td>
750    <td><p>Метод уведомления, заданный на сервере. Одно из следующего:</p>
751      <ul>
752        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li>
753        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li>
754        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li>
755        <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li>
756    </ul></td>
757  </tr>
758</table>
759
760<h3 id="add-reminders">Добавление напоминаний</h3>
761
762<p>Ниже представлен пример добавления напоминания в событие. Напоминание срабатывает за 15
763минут до начала события.</p>
764<pre>
765long eventID = 221;
766...
767ContentResolver cr = getContentResolver();
768ContentValues values = new ContentValues();
769values.put(Reminders.MINUTES, 15);
770values.put(Reminders.EVENT_ID, eventID);
771values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
772Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre>
773
774<h2 id="instances">Таблица экземпляров</h2>
775
776<p>В таблице
777{@link android.provider.CalendarContract.Instances} содержатся данные о времени
778начала и окончания повторений события. В каждой строке этой таблицы
779представлено одно повторение события. Таблица экземпляров недоступна для записи; она предоставляет только
780возможность запрашивать повторения событий. </p>
781
782<p>В таблице ниже перечислены некоторые из полей, которые можно запросить для экземпляра. Обратите внимание,
783что часовой пояс задается параметрами
784{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE}
785и
786{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES}.</p>
787
788
789<table>
790  <tr>
791    <th>Константа</th>
792    <th>Описание</th>
793  </tr>
794  <tr>
795    <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td>
796    <td>Время начала экземпляра в формате UTC (в миллисекундах).</td>
797  </tr>
798  <tr>
799    <td>{@link android.provider.CalendarContract.Instances#END}</td>
800    <td>Время окончания экземпляра в формате UTC (в миллисекундах).</td>
801  </tr>
802  <tr>
803    <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td>
804
805    <td>День окончания экземпляра по юлианскому календарю относительно часового пояса
806приложения «Календарь».
807
808</td>
809  </tr>
810  <tr>
811    <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td>
812
813    <td>Минута окончания экземпляра, вычисленная от полуночи по часовому поясу
814приложения «Календарь».</td>
815
816  </tr>
817  <tr>
818    <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td>
819    <td><code>_ID</code> события для этого экземпляра.</td>
820  </tr>
821    <tr>
822    <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td>
823    <td>День начала экземпляра по юлианскому календарю относительно часового пояса приложения «Календарь».
824 </td>
825  </tr>
826  <tr>
827    <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td>
828
829    <td>Минута начала экземпляра, вычисленная от полуночи по часовому поясу
830приложения «Календарь».
831</td>
832
833  </tr>
834
835</table>
836
837<h3 id="query-instances">Запрос таблицы экземпляров</h3>
838
839<p>Чтобы запросить таблицу экземпляров, необходимо указать промежуток времени для запроса в
840URI. В этом примере {@link android.provider.CalendarContract.Instances}
841получает доступ к полю {@link
842android.provider.CalendarContract.EventsColumns#TITLE} посредством своей реализации
843интерфейса {@link android.provider.CalendarContract.EventsColumns}.
844Другими словами, {@link
845android.provider.CalendarContract.EventsColumns#TITLE}
846возвращается посредством обращения к базе данных, а не путем запроса таблицы {@link
847android.provider.CalendarContract.Instances} с необработанными данными.</p>
848
849<pre>
850private static final String DEBUG_TAG = "MyActivity";
851public static final String[] INSTANCE_PROJECTION = new String[] {
852    Instances.EVENT_ID,      // 0
853    Instances.BEGIN,         // 1
854    Instances.TITLE          // 2
855  };
856
857// The indices for the projection array above.
858private static final int PROJECTION_ID_INDEX = 0;
859private static final int PROJECTION_BEGIN_INDEX = 1;
860private static final int PROJECTION_TITLE_INDEX = 2;
861...
862
863// Specify the date range you want to search for recurring
864// event instances
865Calendar beginTime = Calendar.getInstance();
866beginTime.set(2011, 9, 23, 8, 0);
867long startMillis = beginTime.getTimeInMillis();
868Calendar endTime = Calendar.getInstance();
869endTime.set(2011, 10, 24, 8, 0);
870long endMillis = endTime.getTimeInMillis();
871
872Cursor cur = null;
873ContentResolver cr = getContentResolver();
874
875// The ID of the recurring event whose instances you are searching
876// for in the Instances table
877String selection = Instances.EVENT_ID + " = ?";
878String[] selectionArgs = new String[] {"207"};
879
880// Construct the query with the desired date range.
881Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
882ContentUris.appendId(builder, startMillis);
883ContentUris.appendId(builder, endMillis);
884
885// Submit the query
886cur =  cr.query(builder.build(),
887    INSTANCE_PROJECTION,
888    selection,
889    selectionArgs,
890    null);
891
892while (cur.moveToNext()) {
893    String title = null;
894    long eventID = 0;
895    long beginVal = 0;
896
897    // Get the field values
898    eventID = cur.getLong(PROJECTION_ID_INDEX);
899    beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
900    title = cur.getString(PROJECTION_TITLE_INDEX);
901
902    // Do something with the values.
903    Log.i(DEBUG_TAG, "Event:  " + title);
904    Calendar calendar = Calendar.getInstance();
905    calendar.setTimeInMillis(beginVal);
906    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
907    Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));
908    }
909 }</pre>
910
911<h2 id="intents">Намерения календаря</h2>
912<p>Вашему приложению не нужно запрашивать <a href="#manifest">разрешения</a> на чтение и запись данных календаря. Вместо этого можно использовать намерения, поддерживаемые приложением «Календарь» Android, для обработки операций чтения и записи в этом приложении. В таблице ниже указаны намерения, поддерживаемые поставщиком календаря.</p>
913<table>
914  <tr>
915    <th>Действие</th>
916    <th>URI</th>
917
918    <th>Описание</th>
919    <th>Дополнительные данные</th>
920  </tr>
921  <tr>
922    <td><br>
923    {@link android.content.Intent#ACTION_VIEW VIEW} <br></td>
924    <td><p><code>content://com.android.calendar/time/&lt;ms_since_epoch&gt;</code></p>
925    Сослаться на URI также можно с помощью
926{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI}.
927Пример использования этого намерения представлен в разделе <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Использование намерений для просмотра данных календаря</a>.
928
929    </td>
930    <td>Открытие календаря во время, заданное параметром <code>&lt;ms_since_epoch&gt;</code>.</td>
931    <td>Отсутствуют.</td>
932  </tr>
933  <tr>
934    <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p>
935
936     </td>
937    <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
938
939    Сослаться на URI также можно с помощью
940{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
941Пример использования этого намерения представлен в разделе <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Использование намерений для просмотра данных календаря</a>.
942
943    </td>
944    <td>Просмотр события, указанного с помощью <code>&lt;event_id&gt;</code>.</td>
945
946    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
947      <br>
948      <br>
949    {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
950  </tr>
951
952  <tr>
953    <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td>
954    <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
955
956  Сослаться на URI также можно с помощью
957{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
958Пример использования этого намерения представлен в разделе <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">Использование намерения для редактирования события</a>.
959
960
961    </td>
962    <td>Редактирование события, указанного с помощью <code>&lt;event_id&gt;</code>.</td>
963
964    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
965      <br>
966      <br>
967    {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
968  </tr>
969
970  <tr>
971    <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br>
972    <br>
973    {@link android.content.Intent#ACTION_INSERT INSERT} </td>
974    <td><p><code>content://com.android.calendar/events</code></p>
975
976   Сослаться на URI также можно с помощью
977{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
978Пример использования этого намерения представлен в разделе <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">Использование намерения для редактирования события</a>.
979
980    </td>
981
982    <td>Создание события.</td>
983    <td>Любые из дополнительных данных, указанных в таблице ниже.</td>
984  </tr>
985</table>
986
987<p>В таблице ниже указаны дополнительные данные намерения, которые поддерживаются поставщиком календаря.
988</p>
989<table>
990  <tr>
991    <th>Дополнительные данные намерения</th>
992    <th>Описание</th>
993  </tr>
994  <tr>
995    <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td>
996    <td>Название события.</td>
997  </tr>
998  <tr>
999
1000    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
1001CalendarContract.EXTRA_EVENT_BEGIN_TIME}</td>
1002    <td>Время начала события (в миллисекундах) от эпохи.</td>
1003  </tr>
1004  <tr>
1005    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME
1006CalendarContract.EXTRA_EVENT_END_TIME}</td>
1007
1008    <td>Время окончания события (в миллисекундах) от эпохи.</td>
1009  </tr>
1010  <tr>
1011    <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY
1012CalendarContract.EXTRA_EVENT_ALL_DAY}</td>
1013
1014    <td>Логическое значение, обозначающее, что это событие на весь день. Значение может быть
1015<code>true</code> или <code>false</code>.</td> </tr>
1016  <tr>
1017    <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION
1018Events.EVENT_LOCATION}</td>
1019
1020    <td>Место проведения события.</td>
1021  </tr>
1022  <tr>
1023    <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION
1024Events.DESCRIPTION}</td>
1025
1026    <td>Описание события.</td>
1027  </tr>
1028  <tr>
1029    <td>
1030    {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td>
1031    <td>Адреса эл. почты приглашенных (через запятую).</td>
1032  </tr>
1033  <tr>
1034    <td>
1035    {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td>
1036    <td>Правило повторения для события.</td>
1037  </tr>
1038  <tr>
1039    <td>
1040    {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL
1041Events.ACCESS_LEVEL}</td>
1042
1043    <td>Указывает на то, является ли событие общедоступным или закрытым.</td>
1044  </tr>
1045  <tr>
1046    <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY
1047Events.AVAILABILITY}</td>
1048
1049    <td>Если событие считается как занятое или как свободное время, доступное для планирования.</td>
1050
1051</table>
1052<p>В разделах ниже указан порядок использования этих намерений.</p>
1053
1054
1055<h3 id="intent-insert">Использование намерения для вставки события</h3>
1056
1057<p>С помощью намерения {@link android.content.Intent#ACTION_INSERT INSERT}
1058ваше приложение может отправлять задачи вставки события прямо в приложение «Календарь».
1059Благодаря этому в <a href="#manifest">файл манифеста</a> вашего приложения не нужно включать разрешение {@link
1060android.Manifest.permission#WRITE_CALENDAR}.</p>
1061
1062
1063<p>Когда пользователи работают с приложением, в котором используется такой подход, приложение отправляет
1064их в «Календарь» для завершения добавления события. Намерение {@link
1065android.content.Intent#ACTION_INSERT INSERT} использует дополнительные поля
1066для предварительного указания в форме сведений о событии в приложении «Календарь». После этого пользователи
1067могут отменить событие, отредактировать форму или сохранить событие в своем
1068календаре.</p>
1069
1070
1071
1072<p>Ниже представлен фрагмент кода, в котором на 19 января 2012 г. планируется событие, которое будет проходить с
10737:30 до 8:30. Однако следует учесть некоторые моменты, касающиеся этого примера кода.</p>
1074
1075<ul>
1076  <li>В качестве URI в нем задается
1077{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.</li>
1078
1079  <li>В нем используются дополнительные поля {@link
1080android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
1081CalendarContract.EXTRA_EVENT_BEGIN_TIME} и {@link
1082android.provider.CalendarContract#EXTRA_EVENT_END_TIME
1083CalendarContract.EXTRA_EVENT_END_TIME} для предварительного указания в форме
1084сведений о времени события. Значения времени должны быть указаны в формате UTC и в миллисекундах от
1085эпохи.</li>
1086
1087  <li>В нем используется дополнительное поле {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}
1088для предоставления списка участников, разделенных запятыми (их адреса эл. почты).</li>
1089
1090</ul>
1091<pre>
1092Calendar beginTime = Calendar.getInstance();
1093beginTime.set(2012, 0, 19, 7, 30);
1094Calendar endTime = Calendar.getInstance();
1095endTime.set(2012, 0, 19, 8, 30);
1096Intent intent = new Intent(Intent.ACTION_INSERT)
1097        .setData(Events.CONTENT_URI)
1098        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
1099        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
1100        .putExtra(Events.TITLE, &quot;Yoga&quot;)
1101        .putExtra(Events.DESCRIPTION, &quot;Group class&quot;)
1102        .putExtra(Events.EVENT_LOCATION, &quot;The gym&quot;)
1103        .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
1104        .putExtra(Intent.EXTRA_EMAIL, &quot;rowan@example.com,trevor@example.com&quot;);
1105startActivity(intent);
1106</pre>
1107
1108<h3 id="intent-edit">Использование намерения для редактирования события</h3>
1109
1110<p>Событие можно отредактировать напрямую, как описано в разделе <a href="#update-event">Обновление событий</a>. Благодаря намерению {@link
1111android.content.Intent#ACTION_EDIT EDIT} приложение,
1112у которого нет разрешения, может делегировать редактирование события приложению «Календарь».
1113По завершении редактирования события в приложении «Календарь» пользователи возвращаются
1114в исходное приложение.</p> <p>Ниже представлен пример намерения, который задает
1115новый заголовок для указанного события и позволяет пользователям редактировать событие в приложении «Календарь».</p>
1116
1117
1118<pre>long eventID = 208;
1119Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
1120Intent intent = new Intent(Intent.ACTION_EDIT)
1121    .setData(uri)
1122    .putExtra(Events.TITLE, &quot;My New Title&quot;);
1123startActivity(intent);</pre>
1124
1125<h3 id="intent-view">Использование намерений для просмотра данных календаря</h3>
1126<p>Поставщик календаря позволяет использовать намерение {@link android.content.Intent#ACTION_VIEW VIEW} двумя различными способами:</p>
1127<ul>
1128  <li>Открытие приложения «Календарь» на определенной дате.</li>
1129  <li>Просмотр события.</li>
1130
1131</ul>
1132<p>Ниже представлен пример открытия приложения «Календарь» на определенной дате.</p>
1133<pre>// A date-time specified in milliseconds since the epoch.
1134long startMillis;
1135...
1136Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
1137builder.appendPath(&quot;time&quot;);
1138ContentUris.appendId(builder, startMillis);
1139Intent intent = new Intent(Intent.ACTION_VIEW)
1140    .setData(builder.build());
1141startActivity(intent);</pre>
1142
1143<p>Ниже представлен пример открытия события для его просмотра.</p>
1144<pre>long eventID = 208;
1145...
1146Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
1147Intent intent = new Intent(Intent.ACTION_VIEW)
1148   .setData(uri);
1149startActivity(intent);
1150</pre>
1151
1152
1153<h2 id="sync-adapter">Адаптеры синхронизации</h2>
1154
1155
1156<p>Существуют лишь незначительные различия в том, как приложение и адаптер синхронизации
1157получают доступ к поставщику календаря.</p>
1158
1159<ul>
1160  <li>Адаптеру синхронизации необходимо указать, что он является таковым, задав для параметра {@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER} значение <code>true</code>.</li>
1161
1162
1163  <li>Адаптеру синхронизации необходимо предоставить {@link
1164android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME} и {@link
1165android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} в качестве параметров запроса в URI. </li>
1166
1167  <li>Адаптер синхронизации имеет доступ на запись к большему числу столбцов, чем приложение или виджет.
1168  Например, приложение может изменять только некоторые характеристики календаря,
1169такие как название, отображаемое имя, настройки видимости и
1170синхронизации. Тогда как адаптер синхронизации имеет доступ не только к этим столбцам, но и ко многим другим его характеристикам,
1171таким как цвет календаря, часовой пояс, уровень доступа, местоположение и т. д.
1172Однако адаптер синхронизации ограничен задаваемыми им параметрами <code>ACCOUNT_NAME</code> и
1173<code>ACCOUNT_TYPE</code>.</li> </ul>
1174
1175<p>Ниже представлен метод, который можно использовать, чтобы получить URI для использования вместе с адаптером синхронизации.</p>
1176<pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) {
1177    return uri.buildUpon()
1178        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,&quot;true&quot;)
1179        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
1180        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
1181 }
1182</pre>
1183<p>Пример реализации адаптера синхронизации (который не связан с приложением «Календарь») представлен в статье, посвященной
1184<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>.
1185