你应用程序不需要读写日历数据的权限,它可以使用Android的Calendar应用程序支持的Intent对象来替代你的应用程序的读写权限。下表列出了Calendar提供器支持的Intent对象:
动作 |
资源标识(URI) |
描述 |
附加功能 |
|
VIEW |
content://com.android.calendar/time/<ms_since_epoch> 也能够用CalendarContract.CONTENT_URI来引用这个URI |
打开由<ms_since_epoch>指定时间的日历 |
无 |
|
VIEW |
content://com.android.calendar/events/<event_id> 也能使用Events。CONTENT_URI来引用这个URI。 |
查看由<event_id>指定的的事件 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
EDIT |
Content://com.android.calendar/events/<event_id> 也能使用Events.CONTENT_URI来引用这个URI |
编辑由<event_id>指定的事件 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME |
|
INSERT |
content://com.android.calendar/events 也能够使用Events.CONTENT_URI来引用这个URI |
创建一个事件 |
在下表中列出的任意附加功能 |
下表列出了Calendar提供器支持的Intent对象的附加功能:
Intent对象附加功能 |
描述 |
Events.TITLE |
给事件命名 |
CalendarContract.EXTRA_EVENT_BEGIN_TIME |
从纪元开始用毫秒设定事件的开始时间 |
CalendarContract.EXTRA_EVENT_END_TIME |
从纪元开始用毫秒设定事件的结束时间 |
CalendarContract.EXTRA_EVENT_ALL_DAY |
一个布尔值,指定事件是否是全天的。 |
Events.EVENT_LOCATION |
事件的地点 |
Events.DESCRIPTION |
事件的描述 |
Intent.EXTRA_EMALL |
用逗号分开的受邀者电子邮件地址列表 |
Events.RRULE |
事件的重复规则 |
Events.ACCESS_LEVEL |
事件是私有还是共有的 |
Events.AVAILABILITY |
预定事件是在忙时计数还是在闲时计数 |
以下介绍如何使用这些Intent对象:
1. 使用插入事件的Intent对象
使用INSERT类型的Intent对象会让你的应用程序把事件的插入的任务交给Calendar应用自己。用这种方法,你的应用程序不需要在清单文件中生命WRITE_CALENDAR权限。
当用户运行使用这种方法的应用程序时,应用程序会借助Intent对象把事件信息发送给Calendar应用程序来完成添加事件的处理。INSERT类型的Intent对象使用附加字段来预装一个带有Calendar应用中事件详细信息的表单。为了编辑表单的需要,用户可以取消这个事件,也可以把事件保存到它们的日历中。
以下代码段规划了一个在2011年1月19日上午7:30到8:30运行的事件。代码说明如下:
A.它指定Events.CONTENT_URI作为Uri;
B.它使用CalendarContract.EXTRA_EVENT_BEGIN_TIME和CalendarContract.EXTRA_EVENT_END_TIME附件字段来预装带有事件时间的表单。这些时间值必须是从纪元开始的UTC毫秒。
C.它使用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);
2. 使用编辑事件的Intent对象
你能够像“更新事件”一节中介绍的那样直接更新一个事件。但是使用EDIT类型的Intent对象允许没有权限的应用程序把要编辑的事件交给Calendar应用程序来处理。当用户在Calendar应用程序中完成编辑事件的处理时,就会返回原来的应用程序。
下面这个例子使用Intent对象给特定的事件设置一个新的标题,并且要用户在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);
3. 使用Intent对象来查看日历数据
Calendar提供器提供了两种使用VIEW类型Intent对象的方法
A.打开一个特殊日期的日历
B.查看一个事件
下例子显示怎样打开一个特殊日期的日历:
// 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);
下例显示了怎样打开一个要查看的事件:
long eventID = 208;
...
Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(uri);
startActivity(intent);
同步适配器
应用程序和同步适配器访问Calendar提供器的方式仅有较小的差异:
1. 同步适配器需要通过把CALLER_IS_SYNCADAPTER设置为true来指定它是一个同步适配器;
2. 同步适配器需要提供一个ACCOUNT_NAME和ACCOUNT_TYPE作为URI中的查询参数;
3. 同步适配器有写访问权限的列比应用程序或widget要多。例如,应用程序只能修改一些日历的字符,如名字、显示名、可见设置、以及日历是否被同步。同步适配器不仅能够访问这些列,而且还有一些其他列,如日历的颜色、时区、访问级别、地点等等。但是同步适配器要受到ACCOUNT_NAME和ACCOUNT_TYPE的限制。
你能够使用下面的这个帮助器方法来返回一个给同步适配器使用的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();
}