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><class></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событии —например, заголовок события, место проведения, время начала, время 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<?xml version="1.0" encoding="utf-8"?> 201<manifest xmlns:android="http://schemas.android.com/apk/res/android"...> 202 <uses-sdk android:minSdkVersion="14" /> 203 <uses-permission android:name="android.permission.READ_CALENDAR" /> 204 <uses-permission android:name="android.permission.WRITE_CALENDAR" /> 205 ... 206</manifest> 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> 299— com.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>"_id=?"</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, "Trevor's Calendar"); 365Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID); 366int rows = getContentResolver().update(updateUri, values, null, null); 367Log.i(DEBUG_TAG, "Rows updated: " + 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>"PT1H"</code> обозначает, что событие 440должно длиться один час, а значение <code>"P2W"</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>"FREQ=WEEKLY;COUNT=10;WKST=SU"</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>, — в этом 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>, — в этом 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, "Jazzercise"); 557values.put(Events.DESCRIPTION, "Group workout"); 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идентификатор события необходим для выполнения других действий с календарем — например, для добавления участников или 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>"_id=?"</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, "Kickboxing"); 602updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID); 603int rows = getContentResolver().update(updateUri, values, null, null); 604Log.i(DEBUG_TAG, "Rows updated: " + 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, "Rows deleted: " + 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, "Trevor"); 710values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com"); 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/<ms_since_epoch></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><ms_since_epoch></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/<event_id></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><event_id></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/<event_id></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><event_id></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, "Yoga") 1101 .putExtra(Events.DESCRIPTION, "Group class") 1102 .putExtra(Events.EVENT_LOCATION, "The gym") 1103 .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY) 1104 .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com"); 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, "My New Title"); 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("time"); 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,"true") 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