【翻译】(9-补丁1)日历提供者

 

【翻译】(9-补丁1)日历提供者

 

see

http://developer.android.com/guide/topics/providers/calendar-provider.html

 

原文见

http://developer.android.com/guide/topics/providers/calendar-provider.html

 

-------------------------------

 

Calendar Provider

 

日历提供者

(注:这里的日历其实是指日程安排,不过官方称Google Calendar为Google日历)

 

-------------------------------

 

In this document

 

本文目录

 

* Basics 基础

* User Permissions 用户权限

* Calendars table 日历表

* Querying a calendar 查询日历

* Modifying a calendar 修改日历

* Inserting a calendar 插入日历

* Events table 事件表

* Adding Events 添加事件

* Updating Events 更新事件

* Deleting Events 删除事件

* Attendees table 约会人表

* Adding Attendees 添加约会人

* Reminders table 提醒表

* Adding Reminders 添加提醒

* Instances table 实例表

* Querying the Instances table 查询实例表

* Calendar Intents 日历意图

* Using an intent to insert an event 使用意图插入事件

* Using an intent to edit an event 使用意图编辑事件

* Using intents to view calendar data 使用意图查看日历数据

* Sync Adapters 同步适配器

 

Key classes

 

关键类

 

CalendarContract.Calendars

CalendarContract.Events

CalendarContract.Attendees

CalendarContract.Reminders

 

-------------------------------

 

The Calendar Provider is a repository for a user's calendar events. The Calendar Provider API allows you to perform query, insert, update, and delete operations on calendars, events, attendees, reminders, and so on.

 

日历提供者是用户日历事件的仓库。日历提供者API允许你对日历、事件、约会人、提醒等等执行查询、插入、更新和删除操作。

 

The Calender Provider API can be used by applications and sync adapters. The rules vary depending on what type of program is making the calls. This document focuses primarily on using the Calendar Provider API as an application. For a discussion of how sync adapters are different, see Sync Adapters.

 

日历提供者API可以被应用程序和同步适配器使用。规则的不同依赖于什么类型的程序执行调用。本文档主要把焦点集中作为应用程序来使用日志提供者API。对于同步适配器是怎样的不同的讨论,请参见同步适配器。

 

Normally, to read or write calendar data, an application's manifest must include the proper permissions, described in User Permissions. To make performing common operations easier, the Calendar Provider offers a set of intents, as described in Calendar Intents. These intents take users to the Calendar application to insert, view, and edit events. The user interacts with the Calendar application and then returns to the original application. Thus your application doesn't need to request permissions, nor does it need to provide a user interface to view or create events.

 

一般,为了读取或写入日历数据,一个应用程序的清单必须包含合适的权限,它在用户权限中描述。为了更简单地执行一般操作,日历提供者提供一组意图,在日历意图中描述。这些意图把用户带进日历应用程序以插入、查看以及编辑事件。用户与日历应用程序交互,然后返回到原来的应用程序。这样你的应用程序不需要请求权限,也不需要提供用户界面去查看或创建事件。

 

-------------------------------

 

Basics

 

基础

 

Content providers store data and make it accessible to applications. The content providers offered by the Android platform (including the Calendar Provider) typically expose data as a set of tables based on a relational database model, where each row is a record and each column is data of a particular type and meaning. Through the Calendar Provider API, applications and sync adapters can get read/write access to the database tables that hold a user's calendar data.

 

内容提供者存储数据并使其对于应用程序是可访问。由Android平台提供的内容提供者(包括日历提供者)通常暴露数据作为表的集合,基于关系型数据库模型,每一行是记录而每一列是特定类型和含义的数据。虽然日历提供者API,应用程序和同步适配器可以获得持有用户日历数据的数据库表的读/写访问权。

 

Every content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data set. A content provider that controls multiple data sets (multiple tables) exposes a separate URI for each one. All URIs for providers begin with the string "content://". This identifies the data as being controlled by a content provider. The Calendar Provider defines constants for the URIs for each of its classes (tables). These URIs have the format <class>.CONTENT_URI. For example, Events.CONTENT_URI.

 

每种内容提供者暴露一个公开URI(作为Uri对象封装)唯一地标识它的数据集。一个控制多个数据集(多表)的内容提供者为每一个表暴露一个单独的URI。提供者的所有URI以字符串"content://"开头。它指出数据正在被一个内容提供者控制。日历提供者为它的类(表)的每一个定义URI常量。这些URI的格式是<类名>.CONTENT_URI。例如,Events.CONTENT_URI。

 

Figure 1 shows a graphical representation of the Calendar Provider data model. It shows the main tables and the fields that link them to each other.

 

图1展示日历提供者数据模型的图形图片。它展示主要的表和互相链接的域。

 

(图略:

日历 ->Events.CALENDAR_ID

     -> 事件 ->Attendees.EVENT_ID->约会人

             ->Reminders.EVENT_ID->提醒

             ->Instances.EVENT_ID->实例

->表示一对多

 

Figure 1. Calendar Provider data model.

 

图1。日历提供者数据模型。

 

A user can have multiple calendars, and different calendars can be associated with different types of accounts (Google Calendar, Exchange, and so on).

 

用户可以拥有多个日历,而不同的日历可以被不同类型的账号关联(Google日历,交换,等等)(注:Google Exchange可能指Google Sync,用于同步移动设备和Gmail的日历)

 

The CalendarContract defines the data model of calendar and event related information. This data is stored in a number of tables, listed below.

 

CalendarContract定义日历的数据模型和事件的相关信息。数据被存储在多个表中,列举如下。

 

-------------------------------

 

* Table (Class) Description

 

* 表(类) 描述

 

* CalendarContract.Calendars

 

This table holds the calendar-specific information. Each row in this table contains the details for a single calendar, such as the name, color, sync information, and so on.

 

这个表持有特定于日历的信息。这个表的每一行包含单一日历的细节,诸如名称,颜色,同步信息,等等。

 

* CalendarContract.Events

 

This table holds the event-specific information. Each row in this table has the information for a single event—for example, event title, location, start time, end time, and so on. The event can occur one-time or can recur multiple times. Attendees, reminders, and extended properties are stored in separate tables. They each have an EVENT_ID that references the _ID in the Events table.

 

这个表持有特定于事件的信息。这个表中每一行拥有单一事件的信息——例如,事件标题,位置,开始时间,结束时间,等等。事件可以发生一次或循环多次。约会人,提醒和扩展的属性被存储在单独的表中。它们每个都有一个EVENT_ID,引用事件表中的_ID。

 

* CalendarContract.Instances

 

This table holds the start and end time for each occurrence of an event. Each row in this table represents a single event occurrence. For one-time events there is a 1:1 mapping of instances to events. For recurring events, multiple rows are automatically generated that correspond to multiple occurrences of that event.

 

这个表持有事件每次发生的开始和结束时间。这个表的每一行代表单次事件发生。对于一次性事件,实例是1:1映射至事件的。对于循环事件,自动生成多行,对应那个事件的多次发生。

 

* CalendarContract.Attendees

 

This table holds the event attendee (guest) information. Each row represents a single guest of an event. It specifies the type of guest and the guest's attendance response for the event.

 

这个表持有事件约会人(客户)信息。每行代表事件的单个客户。它指定客户类型和响应事件的客户参与。

 

* CalendarContract.Reminders

 

This table holds the alert/notification data. Each row represents a single alert for an event. An event can have multiple reminders. The maximum number of reminders per event is specified in MAX_REMINDERS, which is set by the sync adapter that owns the given calendar. Reminders are specified in minutes before the event and have a method that determines how the user will be alerted.

 

这个表持有闹钟/提醒数据。每行代表事件的单一闹钟。一个事件可以拥有单个提醒。每个事件的提醒最大数量用MAX_REMINDERS指定,它被拥有给定日历的同步适配器设置。提醒被指定在事件前的一分钟内,并且有方法决定用户如何被闹醒。

 

-------------------------------

 

The Calendar Provider API is designed to be flexible and powerful. At the same time, it's important to provide a good end user experience and protect the integrity of the calendar and its data. To this end, here are some things to keep in mind when using the API:

 

日历提供者API被设计为灵活和强大。同时,重要的是提供一个良好终端用户体验并保护日历和它的数据的完整性。为此,这里有些东西需要在使用这些API时牢记的:

 

* Inserting, updating, and viewing calendar events. To directly insert, modify, and read events from the Calendar Provider, you need the appropriate permissions. However, if you're not building a full-fledged calendar application or sync adapter, requesting these permissions isn't necessary. You can instead use intents supported by Android's Calendar application to hand off read and write operations to that application. When you use the intents, your application sends users to the Calendar application to perform the desired operation in a pre-filled form. After they're done, they're returned to your application. By designing your application to perform common operations through the Calendar, you provide users with a consistent, robust user interface. This is the recommended approach. For more information, see Calendar Intents.

 

* 插入,更新和查看日历事件。为了直接地从日历提供者中插入、修改和阅读事件,你需要合适的权限。然而,如果你现在不构建一个完全成熟的日历应用程序或同步适配器,请求这些权限是没必要的。取而代之的是,你可以使用Android日历应用程序支持的意图传递读写操作给那个应用程序。当你使用意图时,你的应用程序把用户发送到日历提供者以便用预先填好的表单执行期待的操作。在它们完成之后,用户返回到你的应用程序。通过设计你的应用程序通过日历执行一般操作,你向用户提供一个一致的、健壮的用户体验。这是建议的做法。想获取更多信息,请参见日历意图。

 

* Sync adapters. A sync adapter synchronizes the calendar data on a user's device with another server or data source. In the CalendarContract.Calendars and CalendarContract.Events tables, there are columns that are reserved for the sync adapters to use. The provider and applications should not modify them. In fact, they are not visible unless they are accessed as a sync adapter. For more information about sync adapters, see Sync Adapters.

 

* 同步适配器。同步适配器同步用户设备和另一个服务器或数据源的日历数据。在CalendarContract.Calendars和CalendarContract.Events表中,有一些列被保留供同步适配器使用。提供者和应用程序不应该修改它们。事实上,它们是不可见的,除非它们作为同步适配器被访问。关于同步适配器的更多信息,请参见同步适配器。

 

-------------------------------

 

User Permissions

 

用户权限

 

To read calendar data, an application must include the READ_CALENDAR permission in its manifest file. It must include the WRITE_CALENDAR permission to delete, insert or update calendar data:

 

为了读取日历数据,一个应用程序必须在它的清单文件中包含READ_CALENDAR权限。它必须包含WRITE_CALENDAR权限以删除、插入或更新日历数据:

 

-------------------------------

 

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"...>

    <uses-sdk android:minSdkVersion="14" />

    <uses-permission android:name="android.permission.READ_CALENDAR" />

    <uses-permission android:name="android.permission.WRITE_CALENDAR" />

    ...

</manifest>

 

-------------------------------

 

-------------------------------

 

Calendars Table

 

日历表

 

The CalendarContract.Calendars table contains details for individual calendars. The following Calendars columns are writable by both an application and a sync adapter. For a full list of supported fields, see the CalendarContract.Calendars reference.

 

CalendarContract.Calendars表包含单个日历的细节。以下日历列可以被应用程序和同步适配器写入。想获取支持字段的完全列表,请参见CalendarContract.Calendars参考手册。

 

-------------------------------

 

* Constant Description

 

* 常量 描述

 

* NAME The name of the calendar.

 

* NAME 日历名称

 

* CALENDAR_DISPLAY_NAME The name of this calendar that is displayed to the user.

 

* CALENDAR_DISPLAY_NAME 显示给用户的日历名称。

 

* VISIBLE A boolean indicating whether the calendar is selected to be displayed. A value of 0 indicates that events associated with this calendar should not be shown. A value of 1 indicates that events associated with this calendar should be shown. This value affects the generation of rows in the CalendarContract.Instances table.

 

* VISIBLE 一个布尔值指示被选中的日历是否要被显示。0值表示关联这个日历的事件不应该被显示。1值表示与日历关联的事件应该显示。这个值影响CalendarContract.Instances表的行生成。

 

* SYNC_EVENTS A boolean indicating whether the calendar should be synced and have its events stored on the device. A value of 0 says do not sync this calendar or store its events on the device. A value of 1 says sync events for this calendar and store its events on the device.

 

* SYNC_EVENTS 一个布尔值,指示日历是否应该被同步和把它的事件保存在设备上。0值表示不要同步这个日历或存储它的事件在设备上。1值表示同步这个日历的事件并保存它的数据在设备上。

 

-------------------------------

 

Querying a calendar

 

查询日历

 

Here is an example that shows how to get all the calendars for a particular user. For simplicity's sake, in this example the query operation is shown in the user interface thread ("main thread"). In practice, this should be done in an asynchronous thread instead of on the main thread. For more discussion, see Loaders. If you are not just reading data but modifying it, see AsyncQueryHandler.

 

这里有一个示例展示如何获取特定用户的所有日历。为了简单起见,在这个示例中查询操作出现在用户界面线程(“主线程”)中。实际上,这应该在一个异步线程中完成而非在主线程中。想获取更多讨论,请参见加载器。如果你不仅在读数据还在修改它,请参见AsyncQueryHandler。

 

-------------------------------

 

  // Projection array. Creating indices for this array instead of doing

  // dynamic lookups improves performance.

  // 投影数组。给这个数组创建索引而非做动态查找

  // 可以提高性能。

  public static final String[] EVENT_PROJECTION = new String[] {

    Calendars._ID,                           // 0

    Calendars.ACCOUNT_NAME,                  // 1

    Calendars.CALENDAR_DISPLAY_NAME          // 2

  };

 

  // The indices for the projection array above.

  // 上面投影数组的索引。

  private static final int PROJECTION_ID_INDEX = 0;

  private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;

  private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;

 

-------------------------------

 

-------------------------------

 

Why must you include ACCOUNT_TYPE?

 

你为什么必须包含ACCOUNT_TYPE?

 

If you query on a Calendars.ACCOUNT_NAME, you must also include Calendars.ACCOUNT_TYPE in the selection. That is because a given account is only considered unique given both its ACCOUNT_NAME and its ACCOUNT_TYPE. The ACCOUNT_TYPE is the string corresponding to the account authenticator that was used when the account was registered with the AccountManager. There is also a special type of account called ACCOUNT_TYPE_LOCAL for calendars not associated with a device account. ACCOUNT_TYPE_LOCAL accounts do not get synced.

 

如果你查询基于Calendars.ACCOUNT_NAME,你还必须包含Calendars.ACCOUNT_TYPE在选择中。那是因为给定的账户只对于给定它的ACCOUNT_NAME和它的ACCOUNT_TYPE才被认为是唯一的。ACCOUNT_TYPE是一个对应于账户身份验证的字符串,当账户是用AccountManager注册时使用。还有一种用于日历的称为ACCOUNT_TYPE_LOCAL的特殊账户类型,不与设备账户关联。ACCOUNT_TYPE_LOCAL账户不会被同步。

 

-------------------------------

 

In the next part of the example, you construct your query. The selection specifies the criteria for the query. In this example the query is looking for all calendars that have the ACCOUNT_NAME "sampleuser@google.com" and the ACCOUNT_TYPE "com.google". The query returns a Cursor object that you can use to traverse the result set returned by the database query. For more discussion of using queries in content providers, see Content Providers.

 

在示例的下一部分,你构建你的查询。选择指定查询的标准。在这个示例中查询寻找所有拥有ACCOUNT_NAME是"sampleuser@google.com"和ACCOUNT_TYPE是"com.google"的日历。查询返回一个Cursor对象,你可以用它遍历数据库查询返回的结果集。想获取在内容提供者中使用查询的更多讨论,请参见内容提供者。

 

-------------------------------

 

// Run query

// 运行查询

Cursor cur = null;

ContentResolver cr = getContentResolver();

Uri uri = Calendars.CONTENT_URI;   

String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 

                        + Calendars.ACCOUNT_TYPE + " = ?))";

String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google"}; 

// Submit the query and get a Cursor object back. 

// 提交查询并取回Cursor对象

cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

 

-------------------------------

 

This next section uses the cursor to step through the result set. It uses the constants that were set up at the beginning of the example to return the values for each field.

 

下一章节使用游标遍历结果集。它使用在例子开头配置的常量以返回每个域的值。

 

-------------------------------

 

// Use the cursor to step through the returned records

// 使用游标遍历返回的记录

while (cur.moveToNext()) {

    long calID = 0;

    String displayName = null;

    String accountName = null;        

 

    // Get the field values

    // 获取域的值

    calID = cur.getLong(PROJECTION_ID_INDEX);

    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);

    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);

 

    // Do something with the values...

// 处理这些值

   ...

}

 

-------------------------------

 

Modifying a calendar

 

修改日历

 

To perform an update of an calendar, you can provide the _ID of the calendar either as an appended ID to the Uri (withAppendedId()) or as the first selection item. The selection should start with "_id=?", and the first selectionArg should be the _ID of the calendar. You can also do updates by encoding the ID in the URI. This example changes a calendar's display name using the (withAppendedId()) approach:

 

为了执行日历的更新,你可以提供日历的_ID作为尾加到Uri(withAppendedId())的ID或作为第一个选择的条目。选择范围应该以"_id=?"开始,而第一个selectionArg应该是日历的_ID。你还可以通过编码URI中的ID进行更新。此示例使用这种(withAppendedId())方法改变日历的显示名称:

 

-------------------------------

 

private static final String DEBUG_TAG = "MyActivity";

...

long calID = 2;

ContentValues values = new ContentValues();

// The new display name for the calendar

// 日历的新显示名称

values.put(Calendars.CALENDAR_DISPLAY_NAME, "Trevor's Calendar");

Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);

int rows = getContentResolver().update(updateUri, values, null, null);

Log.i(DEBUG_TAG, "Rows updated: " + rows);

 

-------------------------------

 

Inserting a calendar

 

插入日历

 

Calendars are designed to be primarily managed by a sync adapter, so you should only insert new calendars as a sync adapter. For the most part, applications can only make superficial changes to calendars, such as changing the display name. If an application needs to create a local calendar, it can do this by performing the calendar insertion as a sync adapter, using an ACCOUNT_TYPE of ACCOUNT_TYPE_LOCAL. ACCOUNT_TYPE_LOCAL is a special account type for calendars that are not associated with a device account. Calendars of this type are not synced to a server. For a discussion of sync adapters, see Sync Adapters.

 

日历被设计成主要被一个同步适配器管理,所以你应该只插入新的日历作为同步适配器。对于大部分地方,应用程序可以只对日历作出表面的改变,诸如改变显示名称。如果一个应用程序需要创建一个本地日历,它可以通过执行日历插入作为日历适配器来做到,使用ACCOUNT_TYPE_LOCAL的一个ACCOUNT_TYPE。ACCOUNT_TYPE_LOCAL是一个日历的特殊账号类型,它没有关联到一个设备账户。此类日历不和服务器同步。想获取同步适配器的讨论,请参见同步适配器。

 

-------------------------------

 

Events Table

 

事件表

 

The CalendarContract.Events table contains details for individual events. To add, update, or delete events, an application must include the WRITE_CALENDAR permission in its manifest file.

 

CalendarContract.Events表包含单个事件的细节。为了添加、更新或删除事件,应用程序必须在它的清单文件中包含WRITE_CALENDAR权限。

 

The following Events columns are writable by both an application and a sync adapter. For a full list of supported fields, see the CalendarContract.Events reference.

 

以下事件列可以被应用程序或同步适配器写入。关于支持字段的完整列表,请参见CalendarContract.Events参考手册。

 

-------------------------------

 

* Constant Description

 

* 内容 描述

 

* CALENDAR_ID The _ID of the calendar the event belongs to.

 

* CALENDAR_ID 事件所属的日历的_ID。

 

* ORGANIZER Email of the organizer (owner) of the event.

 

* ORGANIZER 事件组织者(拥有人)的电子邮件。

 

* TITLE The title of the event.

 

* TITLE 事件标题

 

* EVENT_LOCATION Where the event takes place.

 

* EVENT_LOCATION 事件发生地点。

 

* DESCRIPTION The description of the event.

 

* DESCRIPTION 事件描述

 

* DTSTART The time the event starts in UTC milliseconds since the epoch.

 

* DTSTART 事件开始的时间,以UTC毫秒为单位,从公元纪年算起。

 

* DTEND The time the event ends in UTC milliseconds since the epoch.

 

* DTEND 事件结束的时间,以UTC毫秒为单位,从公元纪年算起。

 

* EVENT_TIMEZONE The time zone for the event.

 

* EVENT_TIMEZONE 事件的时区。

 

* EVENT_END_TIMEZONE The time zone for the end time of the event.

 

* EVENT_END_TIMEZONE 事件结束时间的时区

 

* DURATION The duration of the event in RFC5545 format. For example, a value of "PT1H" states that the event should last one hour, and a value of "P2W" indicates a duration of 2 weeks.

 

* DURATION 时间的持续时间,RFC5545格式。例如,"PT1H"值表示事件已经持续一个小时,而"P2W"值表示持续2周。

 

* ALL_DAY A value of 1 indicates this event occupies the entire day, as defined by the local time zone. A value of 0 indicates it is a regular event that may start and end at any time during a day.

 

* ALL_DAY 值为1表示这个事件站了整整一天,正如本地时区所定义的那样。值为0表示这是一次常规事件,可能开始和结束于一天中的任意时候。

 

* RRULE The recurrence rule for the event format. For example, "FREQ=WEEKLY;COUNT=10;WKST=SU". You can find more examples here.

 

* RRULE 事件格式的循环规则。例如,"FREQ=WEEKLY;COUNT=10;WKST=SU"。你可以在这里找到更多例子。

 

* RDATE The recurrence dates for the event. You typically use RDATE in conjunction with RRULE to define an aggregate set of repeating occurrences. For more discussion, see the RFC5545 spec.

 

* RDATE 事件的循环日期。你特别地使用RDATE配合RRULE定义重复发生的总集合。想获取更多讨论,请参见RFC5545规范。(注:RFC5545规范是指Internet Calendaring and Scheduling Core Object Specification (iCalendar),互联网日历和日程核心对象规范(iCalendar))

 

* AVAILABILITY If this event counts as busy time or is free time that can be scheduled over.

 

* AVAILABILITY 这个事件是否算起来是繁忙时间还是空闲时间可以放入日程。

 

* GUESTS_CAN_MODIFY Whether guests can modify the event.

 

* GUESTS_CAN_MODIFY 客户是否可以修改事件

 

* GUESTS_CAN_INVITE_OTHERS Whether guests can invite other guests.

 

* GUESTS_CAN_INVITE_OTHERS 客户是否可以邀请其他客户。

 

* GUESTS_CAN_SEE_GUESTS Whether guests can see the list of attendees.

 

* GUESTS_CAN_SEE_GUESTS 客户是否可以看到约会人列表。

 

-------------------------------

 

Adding Events

 

添加事件

 

When your application inserts a new event, we recommend that you use an INSERT Intent, as described in Using an intent to insert an event. However, if you need to, you can insert events directly. This section describes how to do this.

 

当你的应用程序插入一个新事件时,我们建议你使用INSERT意图,正如在使用意图插入事件的章节描述的那样。本节描述如何做到这一单。

 

Here are the rules for inserting a new event:

 

这里是插入新事件的规则:

 

* You must include CALENDAR_ID and DTSTART.

 

* 你必须包含CALENDAR_ID和DTSTART。

 

* You must include an EVENT_TIMEZONE. To get a list of the system's installed time zone IDs, use getAvailableIDs(). Note that this rule does not apply if you're inserting an event through the INSERT Intent, described in Using an intent to insert an event—in that scenario, a default time zone is supplied.

 

* 你必须包含一个EVENT_TIMEZONE。为了获取系统安装时区ID的列表,请使用getAvailableIDs()。注意如果你正在通过INSERT意图插入事件,这个规则不会被应用,这在使用意图插入事件章节中描述——在那种场景下,提供的是默认时区。

 

* For non-recurring events, you must include DTEND.

 

* 对于非循环的事件,你必须包含DTEND。

 

* For recurring events, you must include a DURATION in addition to RRULE or RDATE. Note that this rule does not apply if you're inserting an event through the INSERT Intent, described in Using an intent to insert an event—in that scenario, you can use an RRULE in conjunction with DTSTART and DTEND, and the Calendar application converts it to a duration automatically.

 

* 对于循环的事件,你必须包含一个DURATION加上RRULE或RDATE。注意入股欧尼正在通过INSERT意图插入事件,这个规则不被应用,在使用意图插入事件的章节中描述——在那种长江下,你可以使用一个RRULE组合DTSTART和DTEND,而日历应用程序会自动把它转换为持续时间。

 

Here is an example of inserting an event. This is being performed in the UI thread for simplicity. In practice, inserts and updates should be done in an asynchronous thread to move the action into a background thread. For more information, see AsyncQueryHandler.

 

这里有一个插入事件的示例。简单起见,它在用户界面线程中执行。实际上,插入和更新应该在一个异步线程中进行,把动作移动进一个后台线程中。想获取更多信息,请参见AsyncQueryHandler。

 

-------------------------------

 

long calID = 3;

long startMillis = 0; 

long endMillis = 0;     

Calendar beginTime = Calendar.getInstance();

beginTime.set(2012, 9, 14, 7, 30);

startMillis = beginTime.getTimeInMillis();

Calendar endTime = Calendar.getInstance();

endTime.set(2012, 9, 14, 8, 45);

endMillis = endTime.getTimeInMillis();

...

 

ContentResolver cr = getContentResolver();

ContentValues values = new ContentValues();

values.put(Events.DTSTART, startMillis);

values.put(Events.DTEND, endMillis);

values.put(Events.TITLE, "Jazzercise");

values.put(Events.DESCRIPTION, "Group workout");

values.put(Events.CALENDAR_ID, calID);

values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");

Uri uri = cr.insert(Events.CONTENT_URI, values);

 

// get the event ID that is the last element in the Uri

// 获取在Uri中是最后元素的事件ID

long eventID = Long.parseLong(uri.getLastPathSegment());

// 

// ... do something with event ID

// ... 处理事件ID

//

//

 

-------------------------------

 

Note: See how this example captures the event ID after the event is created. This is the easiest way to get an event ID. You often need the event ID to perform other calendar operations—for example, to add attendees or reminders to an event.

 

注意:看看这个示例如何在事件被创建后捕获事件ID。这是获取事件ID的最简单方式。你尝尝需要事件ID去执行其它日历操作——例如,把约会人或提醒添加到事件。

 

-------------------------------

 

Updating Events

 

更新事件

 

When your application wants to allow the user to edit an event, we recommend that you use an EDIT Intent, as described in Using an intent to edit an event. However, if you need to, you can edit events directly. To perform an update of an Event, you can provide the _ID of the event either as an appended ID to the Uri (withAppendedId()) or as the first selection item. The selection should start with "_id=?", and the first selectionArg should be the _ID of the event. You can also do updates using a selection with no ID. Here is an example of updating an event. It changes the title of the event using the withAppendedId() approach:

 

当你的应用程序希望允许用户编辑一个事件时,我们建议你使用EDIT意图,正如使用意图编辑事件的章节中描述的那样。然而,如果你需要这样,你可以直接编辑事件,为了执行事件的更新,你可以提供事件的_ID,或者作为一个Uri的尾加ID(用withAppendedId()),或者作为第一个选择条目。选择范围应该以"_id=?"开始,而第一个selectionArg应该是事件的_ID。你还可以使用一个不带ID的选择进行更新。这里有一个更新事件的示例。它用withAppendedId()方法改变事件的标题:

 

-------------------------------

 

private static final String DEBUG_TAG = "MyActivity";

...

long eventID = 188;

...

ContentResolver cr = getContentResolver();

ContentValues values = new ContentValues();

Uri updateUri = null;

// The new title for the event

// 事件的新标题

values.put(Events.TITLE, "Kickboxing"); 

myUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);

int rows = getContentResolver().update(updateUri, values, null, null);

Log.i(DEBUG_TAG, "Rows updated: " + rows);  

 

-------------------------------

 

Deleting Events

 

删除事件

 

You can delete an event either by its _ID as an appended ID on the URI, or by using standard selection. If you use an appended ID, you can't also do a selection. There are two versions of delete: as an application and as a sync adapter. An application delete sets the deleted column to 1. This flag that tells the sync adapter that the row was deleted and that this deletion should be propagated to the server. A sync adapter delete removes the event from the database along with all its associated data. Here is an example of application deleting an event through its _ID:

 

你可以删除一个事件,或者通过它的_ID作为URI的尾加ID,或者通过使用标准的选择。如果你使用一个尾加ID,你还不能执行选择。有两种删除的版本:作为应用程序和作为同步适配器。应用程序的删除设置被删除的列为1。这个标志告诉同步适配器,行已经被删除,而这个删除应该被传播到服务器。同步适配器的删除从数据库中移除事件以及它的所有相关数据。这里是应用程序通过事件的_ID删除事件的示例。

 

-------------------------------

 

private static final String DEBUG_TAG = "MyActivity";

...

long eventID = 201;

...

ContentResolver cr = getContentResolver();

ContentValues values = new ContentValues();

Uri deleteUri = null;

deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);

int rows = getContentResolver().delete(deleteUri, null, null);

Log.i(DEBUG_TAG, "Rows deleted: " + rows); 

 

-------------------------------

 

Attendees Table

 

约会人表

 

Each row of the CalendarContract.Attendees table represents a single attendee or guest of an event. Calling query() returns a list of attendees for the event with the given EVENT_ID. This EVENT_ID must match the _ID of a particular event.

 

CalendarContract.Attendees表的每一行代表事件的一个单一约会人或客户。调用query()会返回带EVENT_ID的事件约会人的列表。这个EVENT_ID必须匹配特定事件的_ID。

 

The following table lists the writable fields. When inserting a new attendee, you must include all of them except ATTENDEE_NAME.

 

以下表列出可写的域。当插入一个新约会人时,你必须包含它们的所有,除了ATTENDEE_NAME。

 

-------------------------------

 

* Constant Description

 

* 常数 描述

 

* EVENT_ID The ID of the event.

 

* EVENT_ID 事件的ID。

 

* ATTENDEE_NAME The name of the attendee.

 

* ATTENDEE_NAME 约会人的名称

 

* ATTENDEE_EMAIL The email address of the attendee.

 

* ATTENDEE_EMAIL 约会人的电子邮件地址。

 

* ATTENDEE_RELATIONSHIP The relationship of the attendee to the event. One of:

 

* ATTENDEE_RELATIONSHIP 事件约会人的关系。以下的其中之一:

 

* RELATIONSHIP_ATTENDEE

* RELATIONSHIP_NONE

* RELATIONSHIP_ORGANIZER

* RELATIONSHIP_PERFORMER

* RELATIONSHIP_SPEAKER

 

* ATTENDEE_TYPE The type of attendee. One of:

 

* ATTENDEE_TYPE 约会人的类型。以下的其中之一:

 

* TYPE_REQUIRED

* TYPE_OPTIONAL

 

* ATTENDEE_STATUS The attendance status of the attendee. One of:

 

* ATTENDEE_STATUS 约会人的参加状态。以下的其中之一:

 

* ATTENDEE_STATUS_ACCEPTED

* ATTENDEE_STATUS_DECLINED

* ATTENDEE_STATUS_INVITED

* ATTENDEE_STATUS_NONE

* ATTENDEE_STATUS_TENTATIVE

 

-------------------------------

 

Adding Attendees

 

添加约会人

 

Here is an example that adds a single attendee to an event. Note that the EVENT_ID is required:

 

这里有一个添加单一约会人到事件的例子。注意EVENT_ID是必需的。

 

-------------------------------

 

long eventID = 202;

...

ContentResolver cr = getContentResolver();

ContentValues values = new ContentValues();

values.put(Attendees.ATTENDEE_NAME, "Trevor");

values.put(Attendees.ATTENDEE_EMAIL, "trevor@example.com");

values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);

values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);

values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);

values.put(Attendees.EVENT_ID, eventID);

Uri uri = cr.insert(Attendees.CONTENT_URI, values);

 

-------------------------------

 

Reminders Table

 

提醒表

 

Each row of the CalendarContract.Reminders table represents a single reminder for an event. Calling query() returns a list of reminders for the event with the given EVENT_ID.

 

CalendarContract.Reminders表的每一行代表事件的单一提醒。调用query()返回给定EVENT_ID的事件的提醒列表。

 

The following table lists the writable fields for reminders. All of them must be included when inserting a new reminder. Note that sync adapters specify the types of reminders they support in the CalendarContract.Calendars table. See ALLOWED_REMINDERS for details.

 

以下表格列出提醒的可写字段。当插入新提醒时,它们全都必须被包含。注意同步适配器指定它们在CalendarContract.Calendars表中支持的提醒类型。详细请见ALLOWED_REMINDERS。

 

-------------------------------

 

* Constant Description

 

* 常数 描述

 

* EVENT_ID The ID of the event.

 

* EVENT_ID 事件ID。

 

* MINUTES The minutes prior to the event that the reminder should fire.

 

* MINUTES 在事件发生前提醒应该响起的分钟。

 

* METHOD The alarm method, as set on the server. One of:

 

* METHOD 闹钟方法,正如在服务器上设置的。以下其中之一

 

* METHOD_ALERT

* METHOD_DEFAULT

* METHOD_EMAIL

* METHOD_SMS

 

-------------------------------

 

Adding Reminders

 

添加提醒

 

This example adds a reminder to an event. The reminder fires 15 minutes before the event.

 

这个示例添加提醒到事件。提醒在事件发生前持续响15分钟。

 

-------------------------------

 

long eventID = 221;

...

ContentResolver cr = getContentResolver();

ContentValues values = new ContentValues();

values.put(Reminders.MINUTES, 15);

values.put(Reminders.EVENT_ID, eventID);

values.put(Reminders.METHOD, Reminders.METHOD_ALERT);

Uri uri = cr.insert(Reminders.CONTENT_URI, values);

 

-------------------------------

 

-------------------------------

 

Instances Table

 

实例表

 

The CalendarContract.Instances table holds the start and end time for occurrences of an event. Each row in this table represents a single event occurrence. The instances table is not writable and only provides a way to query event occurrences.

 

CalendarContract.Instances表持有事件发生的开始和结束时间。这个表的每一行代表单一事件的发生。实例表不是可写的,并且只提供一种方式查询事件的发生。

 

The following table lists some of the fields you can query on for an instance. Note that time zone is defined by KEY_TIMEZONE_TYPE and KEY_TIMEZONE_INSTANCES.

 

以下表格列出你可以查询实例所基于的一些字段。注意时区由KEY_TIMEZONE_TYPE和KEY_TIMEZONE_INSTANCES定义。

 

-------------------------------

 

* Constant Description

 

* 常数 描述

 

* BEGIN The beginning time of the instance, in UTC milliseconds.

 

* BEGIN 实例的开始时间,以UTC毫秒为单位。

 

* END The ending time of the instance, in UTC milliseconds.

 

* END 实例的结束时间,以UTC毫秒为单位。

 

* END_DAY The Julian end day of the instance, relative to the Calendar's time zone.

 

* END_DAY 实例的公历(注:Julian calendar是格里历、即儒略历、公历,而Lunar calendar是阴历)结束时间,相对于日历时区。

 

* END_MINUTE The end minute of the instance measured from midnight in the the Calendar's time zone.

 

* END_MINUTE 实例的结束分钟,从日历时区的凌晨算起。

 

* EVENT_ID The _ID of the event for this instance.

 

* EVENT_ID 这个实例的事件_ID。

 

* START_DAY The Julian start day of the instance, relative to the Calendar's time zone.

 

* START_DAY 实例的公历开始时间,相对于日历时区。

 

* START_MINUTE The start minute of the instance measured from midnight, relative to the Calendar's time zone.

 

* START_MINUTE 实例的开始分钟,从日历时区的凌晨算起。

 

-------------------------------

 

Querying the Instances table

 

查询实例表

 

To query the Instances table, you need to specify a range time for the query in the URI. In this example, CalendarContract.Instances gets access to the TITLE field through its implementation of the CalendarContract.EventsColumns interface. In other words, TITLE is returned through a database view, not through querying the raw CalendarContract.Instances table.

 

为了查询实例表,你需要在URI中指定请求的范围时间。在这个例子中,CalendarContract.Instances通过它对CalendarContract.EventsColumns接口的实现获取TITLE字段的访问权。换言之,TITLE通过数据库视图返回,而非通过查询原始的CalendarContract.Instances表。

 

-------------------------------

 

private static final String DEBUG_TAG = "MyActivity";

public static final String[] INSTANCE_PROJECTION = new String[] {

    Instances.EVENT_ID,      // 0

    Instances.BEGIN,         // 1

    Instances.TITLE          // 2

  };

 

// The indices for the projection array above.

// 上面投影数组索引

private static final int PROJECTION_ID_INDEX = 0;

private static final int PROJECTION_BEGIN_INDEX = 1;

private static final int PROJECTION_TITLE_INDEX = 2;

...

 

// Specify the date range you want to search for recurring

// event instances

// 指定你想搜索循环事件实例的数据范围

Calendar beginTime = Calendar.getInstance();

beginTime.set(2011, 9, 23, 8, 0);

long startMillis = beginTime.getTimeInMillis();

Calendar endTime = Calendar.getInstance();

endTime.set(2011, 10, 24, 8, 0);

long endMillis = endTime.getTimeInMillis();

 

Cursor cur = null;

ContentResolver cr = getContentResolver();

 

// The ID of the recurring event whose instances you are searching

// for in the Instances table

// 它的实例你正在在实例表中搜索其实例的循环事件ID

String selection = Instances.EVENT_ID + " = ?";

String[] selectionArgs = new String[] {"207"};

 

// Construct the query with the desired date range.

// 用期待的数据范围构造查询

Uri.Builder builder = Instances.CONTENT_URI.buildUpon();

ContentUris.appendId(builder, startMillis);

ContentUris.appendId(builder, endMillis);

 

// Submit the query

// 提交查询

cur =  cr.query(builder.build(), 

    INSTANCE_PROJECTION, 

    selection, 

    selectionArgs, 

    null);

 

while (cur.moveToNext()) {

    String title = null;

    long eventID = 0;

    long beginVal = 0;    

 

    // Get the field values

    // 获取字段值

    eventID = cur.getLong(PROJECTION_ID_INDEX);

    beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);

    title = cur.getString(PROJECTION_TITLE_INDEX);

 

    // Do something with the values. 

    // 处理这些值

    Log.i(DEBUG_TAG, "Event:  " + title); 

    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(beginVal);  

    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");

    Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));    

    }

 }

 

-------------------------------

 

Calendar Intents

 

日历意图

 

Your application doesn't need permissions to read and write calendar data. It can instead use intents supported by Android's Calendar application to hand off read and write operations to that application. The following table lists the intents supported by the Calendar Provider:

 

你的应用程序不需要权限读写日历数据。可以改用Android日历应用程序支持的意图把读写操作传递给那个应用程序。以下表格列出日历提供者支持的意图:

 

-------------------------------

 

* Action URI Description Extras

 

* 动作 URI 描述 额外数据

 

* VIEW 

content://com.android.calendar/time/<ms_since_epoch>

 

You can also refer to the URI with CalendarContract.CONTENT_URI. For an example of using this intent, see Using intents to view calendar data.

 

你还可以用CalendarContract.CONTENT_URI引用这个URI。关于使用意图的示例,请参见使用意图查看日历数据。

 

Open calendar to the time specified by <ms_since_epoch>.

 

打开由<ms_since_epoch>指定时间的日历。

 

None.

 

 无。

 

* VIEW

content://com.android.calendar/events/<event_id>

 

You can also refer to the URI with Events.CONTENT_URI. For an example of using this intent, see Using intents to view calendar data.

 

你还可以用Events.CONTENT_URI引用这个URI。想获取使用这种意图的示例,请参见使用意图查看日历数据。  

 

View the event specified by <event_id>.

 

查看由<event_id>指定的事件。

 

CalendarContract.EXTRA_EVENT_BEGIN_TIME

CalendarContract.EXTRA_EVENT_END_TIME

 

* EDIT

content://com.android.calendar/events/<event_id>

 

You can also refer to the URI with Events.CONTENT_URI. For an example of using this intent, see Using an intent to edit an event.

 

你还可以用Events.CONTENT_URI引用这个URI。想获取使用这种意图的示例,请参见使用意图编辑事件章节。 

 

Edit the event specified by <event_id>.

 

编辑由<event_id>指定的事件。

 

CalendarContract.EXTRA_EVENT_BEGIN_TIME

CalendarContract.EXTRA_EVENT_END_TIME

 

* EDIT 

INSERT

content://com.android.calendar/events

 

You can also refer to the URI with Events.CONTENT_URI. For an example of using this intent, see Using an intent to insert an event.

 

你还可以用Events.CONTENT_URI引用这个URI。想获取使用这种意图的示例,请参见使用意图插入事件章节。

 

Create an event.

 

创建一个事件。

 

Any of the extras listed in the table below.

 

列举在下面的表格中的任意额外数据。

 

-------------------------------

 

The following table lists the intent extras supported by the Calendar Provider:

 

以下表格列出日历提供者支持的意图额外数据:

 

-------------------------------

 

* Intent Extra Description

 

* 意图额外数据 描述

 

* Events.TITLE Name for the event.

 

* Events.TITLE 事件名称。

 

* CalendarContract.EXTRA_EVENT_BEGIN_TIME Event begin time in milliseconds from the epoch.

 

* CalendarContract.EXTRA_EVENT_BEGIN_TIME 事件开始时间,以毫秒为单位,从公元纪年算起。

 

* CalendarContract.EXTRA_EVENT_END_TIME Event end time in milliseconds from the epoch.

 

* CalendarContract.EXTRA_EVENT_END_TIME 事件结束时间,以毫秒为单位,从公元纪年算起。

 

* CalendarContract.EXTRA_EVENT_ALL_DAY A boolean that indicates that an event is all day. Value can be true or false.

 

* CalendarContract.EXTRA_EVENT_ALL_DAY 布尔值,表示事件是一整天的。值可以是true或false。

 

* Events.EVENT_LOCATION Location of the event.

 

* Events.EVENT_LOCATION 事件地点。

 

* Events.DESCRIPTION Event description.

 

* Events.DESCRIPTION 事件描述

 

* Intent.EXTRA_EMAIL Email addresses of those to invite as a comma-separated list.

 

* Intent.EXTRA_EMAIL 邀请人的电子邮件的地址,作为逗号分隔列表。

 

* Events.RRULE The recurrence rule for the event.

 

* Events.RRULE 事件循环规则。

 

* Events.ACCESS_LEVEL Whether the event is private or public.

 

* Events.ACCESS_LEVEL 事件是私有还是公开。

 

* Events.AVAILABILITY If this event counts as busy time or is free time that can be scheduled over.

 

* Events.AVAILABILITY 这个事件是计算为繁忙时间还是空闲时间,可以被计划进行。

 

-------------------------------

 

The following sections describe how to use these intents.

 

以下章节描述如何使用这些意图。

 

Using an intent to insert an event

 

使用意图插入事件

 

Using the INSERT Intent lets your application hand off the event insertion task to the Calendar itself. With this approach, your application doesn't even need to have the WRITE_CALENDAR permission included in its manifest file.

 

使用INSERT意图让你的应用程序传递事件插入任务给日历自身。用这种方法,你的应用程序甚至不需要在清单文件中拥有WRITE_CALENDAR权限。

 

When users run an application that uses this approach, the application sends them to the Calendar to finish adding the event. The INSERT Intent uses extra fields to pre-populate a form with the details of the event in the Calendar. Users can then cancel the event, edit the form as needed, or save the event to their calendars.

 

当用户运行一个使用此方法的应用程序时,应用程序发送它们给日历以完成添加事件的工作。INSERT意图使用额外字段以在日历中预先生成一个带有事件细节的表单。然后用户可以取消事件、需要时编辑表单,或保存事件到它们的日历中。

 

Here is a code snippet that schedules an event on January 19, 2012, that runs from 7:30 a.m. to 8:30 a.m. Note the following about this code snippet:

 

这里有一段代码片段,计划事件发生在2012年1月19日,从上午7:30到上午8:30之间运行。注意关于这段代码片段的以下问题:

 

* It specifies Events.CONTENT_URI as the Uri.

 

* 它指定Events.CONTENT_URI作为Uri。

 

* It uses the CalendarContract.EXTRA_EVENT_BEGIN_TIME and CalendarContract.EXTRA_EVENT_END_TIME extra fields to pre-populate the form with the time of the event. The values for these times must be in UTC milliseconds from the epoch.

 

* 它使用CalendarContract.EXTRA_EVENT_BEGIN_TIME和CalendarContract.EXTRA_EVENT_END_TIME额外字段以预生成带有事件时间的表单。这些时间值必须以UTC(注:UTC是世界标准时间的缩写)毫秒为单位,从公元纪年算起。

 

* It uses the Intent.EXTRA_EMAIL extra field to provide a comma-separated list of invitees, specified by email address.

 

* 它使用Intent.EXTRA_EMAIL额外字段以提供一个逗号分隔的约会人列表,用电子邮箱地址指定。

 

-------------------------------

 

Calendar beginTime = Calendar.getInstance();

beginTime.set(2012, 0, 19, 7, 30);

Calendar endTime = Calendar.getInstance();

endTime.set(2012, 0, 19, 8, 30);

Intent intent = new Intent(Intent.ACTION_INSERT)

        .setData(Events.CONTENT_URI)

        .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())

        .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())

        .putExtra(Events.TITLE, "Yoga")

        .putExtra(Events.DESCRIPTION, "Group class")

        .putExtra(Events.EVENT_LOCATION, "The gym")

        .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)

        .putExtra(Intent.EXTRA_EMAIL, "rowan@example.com,trevor@example.com");

startActivity(intent);

 

-------------------------------

 

Using an intent to edit an event

 

使用意图编辑事件

 

You can update an event directly, as described in Updating events. But using the EDIT Intent allows an application that doesn't have permission to hand off event editing to the Calendar application. When users finish editing their event in Calendar, they're returned to the original application.

 

你可以直接更新一个事件,正如在更新事件中描述的那样。但是使用EDIT意图允许没有权限的应用程序传递事件编辑给日历应用程序。当用户完成编辑他们在日历中的事件时,他们返回到原来的应用程序中。

 

Here is an example of an intent that sets a new title for a specified event and lets users edit the event in the Calendar.

 

这里有一个意图示例,设置一个指定事件的新标题并让用户编辑日历中的事件。

 

-------------------------------

 

long eventID = 208;

Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);

Intent intent = new Intent(Intent.ACTION_EDIT)

    .setData(uri)

    .putExtra(Events.TITLE, "My New Title");

startActivity(intent);

 

-------------------------------

 

Using intents to view calendar data

 

使用意图查看日历数据

 

Calender Provider offers two different ways to use the VIEW Intent:

 

日历提供者提供两种不同的使用VIEW意图的方式:

 

* To open the Calendar to a particular date.

 

* 打开日历到特定的日期。

 

* To view an event.

 

* 查看事件。

 

Here is an example that shows how to open the Calendar to a particular date:

 

-------------------------------

 

// A date-time specified in milliseconds since the epoch.

// 从公元纪年(注:世纪?)算起以毫秒为单位的日期时间。

long startMillis;

...

Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();

builder.appendPath("time");

ContentUris.appendId(builder, startMillis);

Intent intent = new Intent(Intent.ACTION_VIEW)

    .setData(builder.build());

startActivity(intent);

 

-------------------------------

 

Here is an example that shows how to open an event for viewing:

 

这里有一个示例,展示如何打开事件供查看:

 

-------------------------------

 

long eventID = 208;

...

Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);

Intent intent = new Intent(Intent.ACTION_VIEW)

   .setData(uri);

startActivity(intent);

 

-------------------------------

 

Sync Adapters

 

同步适配器

 

There are only minor differences in how an application and a sync adapter access the Calendar Provider:

 

应用程序和同步适配器访问日历提供者只有很少区别:

 

* A sync adapter needs to specify that it's a sync adapter by setting CALLER_IS_SYNCADAPTER to true.

 

* 同步适配器需要通过设置CALLER_IS_SYNCADAPTER为true说明它是同步适配器。

 

* A sync adapter needs to provide an ACCOUNT_NAME and an ACCOUNT_TYPE as query parameters in the URI.

 

* 同步适配器需要提供一个ACCOUNT_NAME和ACCOUNT_TYPE作为URI中的查询参数。

 

* A sync adapter has write access to more columns than an application or widget. For example, an application can only modify a few characteristics of a calendar, such as its name, display name, visibility setting, and whether the calendar is synced. By comparison, a sync adapter can access not only those columns, but many others, such as calendar color, time zone, access level, location, and so on. However, a sync adapter is restricted to the ACCOUNT_NAME and ACCOUNT_TYPE it specified.

 

* 同步适配器拥有比应用程序或部件更多的列的写访问权。例如,应用程序只可以修改少量特性,诸如它的名称、显示名称、可见设置,以及日历是否被同步。比较来说,同步适配器可以访问的不只有那些列,还有其它许多东西,诸如日历颜色,时区,访问级别,位置,等等。然而,同步适配器被限制为它指定的ACCOUNT_NAME和ACCOUNT_TYPE。

 

Here is a helper method you can use to return a URI for use with a sync adapter:

 

这里有一个辅助方法,你可以使用它返回URI,供同步适配器使用:

 

-------------------------------

 

 static Uri asSyncAdapter(Uri uri, String account, String accountType) {

    return uri.buildUpon()

        .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")

        .appendQueryParameter(Calendars.ACCOUNT_NAME, account)

        .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();

 }

 

-------------------------------

 

For a sample implementation of a sync adapter (not specifically related to Calendar), see SampleSyncAdapter.

 

想获得同步适配器的示例实现(不是特定与日历有关),请参见SampleSyncAdapter。

 

Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.

 

除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。

 

Android 4.0 r1 - 17 Nov 2011 21:59

 

Android 4.0 r1 - 21 Dec 2011 3:15

 

-------------------------------

 

patch:

 

1. 2011-12-28

 

Android 4.0 r1 - 21 Dec 2011 3:15

 

The ACCOUNT_TYPE refers to the way that the account is being synced. It is often but not always the domain. For example, an account could be synced through a corporate pop3 sync adapter, in which case the ACCOUNT_TYPE would not be a domain.

 

->

 

The ACCOUNT_TYPE is the string corresponding to the account authenticator that was used when the account was registered with the AccountManager.

 

ACCOUNT_TYPE是一个对应于账户身份验证的字符串,当账户是用AccountManager注册时使用。

 

-------------------------------

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

(此页部分内容基于Android开源项目,以及使用根据创作公共2.5来源许可证描述的条款进行修改)

 

-------------------------------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值