`
huaxin803
  • 浏览: 115558 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android 日历提供器(二)

 
阅读更多
Calendars表

CalendarContract.Calendars表包含了单个日历的详细信息。下表中Calendars表列对应用程序和同步适配器都是可写的。对于这个表支持的完整的字段列表,请看“CalendarContract.Calendars参考”

http://developer.android.com/reference/android/provider/CalendarContract.Calendars.html

常量

描述

NAME

日历的名字

CALENDAR_DISPLAY_NAME

显示给用户的名字

VISIBLE

一个指明被选择的日历是否显示的布尔值。0指明跟这个日历相关联的不应该显示,1指明跟这个日历关联的事件应该显示。这个值会影响CalendarContract.Instances表中行的产生。

SYNC_EVENTS

一个布尔值,指明日历是否应该被同步并在设备上保存其事件。0指明不同步这个日历并在设备上保存事件。1指明同步这个日历并在设备上保存其事件。

查询日历

这是一个显示怎样为特定的用户获取所有日历的例子。为了简单明了,在这个列子中,查询操作被写在了用户界面线程中(“主线程”)。实践中,应该用异步线程来替代主线程做这样的事情。

// 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;

接下来要构造查询。Selection变量指定了查询条件。在这个例子中,要查找所有的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.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

接下来使用游标来遍历结果集,使用常量来返回每个字段的值:

// 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...

   ...
}

修改日历

你能够通过日历的_ID来执行更新处理,这个ID既可以是附加到Uri(用withAppendedId()方法)中的ID,也可以是第一个选择项目的ID。selection变量应用用“_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);

插入日历

Calendars被设计成以同步适配器为主的方式来管理的表,因此你只应该用同步适配器来插入新的日历。大多数情况,应用程序仅能改变日历的外观,如改变显示名字。如果应用程序需要创建一个本地日历,那么它能使用一个ACCOUNT_TYPE_LOCAL的ACCOUNT_TYPE列,通过执行同步适配器的日历插入处理来完成这件事情。ACCOUNT_TYPE_LOCAL是一个特殊的日历账号类型,它不跟设备账号关联。这种类型的日历不同步到服务器。关于同步适配器的讨论,请看“同步适配器”。

Events 表

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

以下Events表列通过应用程序和同步适配器都是可写的。对于这个表的完整的字段列表,请看CalendarContract.Events参考。

常量

描述

CALENDAR_ID

事件所属的日历的_ID

ORGANIZER

事件的组织者(所有者)的电子邮件

TITLE

事件的标题

EVENT_LOCATION

事件发生的地点

DESCRIPTION

事件的描述

DTSTART

事件的启动时间,使用从纪元开始的UTC毫秒计时

DTEND

事件的结束时间,使用从纪元开始的UTC毫秒计时

EVENT_TIMEZONE

事件所针对的时区

EVENT_END_TIMEZONE

针对事件结束时间的时区

DURATION

用RFC5545格式表示的事件持续时间,例如“PT1H”表示事件持续1小时的状态, “P2W”指明2周的持续时间。

ALL_DAY

1指明这个事件会占用整天时间(由本地时区定义的时间);0指明它是一个普通的事件,可以在一天的任何时间开始和结束

RRULE

格式化的事件复发规则(RFC5545)。如“FREQ=WEEKLY;COUNT=10;WKST=SU”。

RDATE

事件的复发日期。通常RDATE要联合RRULE一起使用来定义一个重复发生的事件的合集。

AVAILABILITY

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

GUESTS_CAN_MODIFY

参与者是否能够修改事件

GUESTS_CAN_INVITE_OTHERS

参与者是否能够邀请其他参与者

GUESTS_CAN_SEE_GUESTS

参与者是否能够看到与会者列表

注:RFC5545地址:http://tools.ietf.org/html/rfc5545#section-3.8.2.5

给Events表添加数据

当你的应用程序要插入一个新的事件时,我们推荐你使用INSERT类型Intent对象(在“使用Intent对象来插入事件”一节中介绍)。但是,如果需要,你能够直接插入事件,本节介绍怎样做这件事情。

以下是针对插入一个新的事件的一些规则:

1. 必须包含CALENDAR_ID和DTSTART字段

2. 必须包含EVENT_TIMEZONE字段。使用getAvailableIDs()方法获得系统已安装的时区ID列表。注意如果通过INSTERT类型Intent对象来插入事件,那么这个规则不适用,因为在INSERT对象的场景中会提供一个默认的时区;

3. 对于非重复发生的事件,必须包含DTEND字段;

4. 对重复发生的事件,必须包含一个附加了RRULE或RDATE字段的DURATIION字段。注意,如果通过INSERT类型的Intent对象来插入一个事件,这个规则不适用。因为在这个Intent对象的应用场景中,你能够把RRULE、DTSTART和DTEND字段联合在一起使用,并且Calendar应用程序能够自动的把它转换成一个持续的时间。

以下是插入一个事件的例子,为了简单,这个例子在UI线程中被执行,实际上,插入和更新处理应该在一个后台的线程中异步的执行。有关更多的信息,请看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
long eventID = Long.parseLong(uri.getLastPathSegment());
// 
// ... do something with event ID
//
//

注意:看这个例子在事件被创建后是怎样获取这个事件的ID的,这是获取事件ID的最容易的方法,你会经常需要这个事件ID来执行其他的日历操作---如,给事件添加与会者或提醒。

更新事件

当你的应用程序想要允许用户编辑一个事件时,我们推荐你使用EDIT类型的Intent对象,但是如果需要,你能够直接编辑事件。你能够提供要编辑的事件的_ID来执行事件的更新处理,这个ID既可以是附加给Uri的ID(用withAppendedId()方法),也可以是第一个选择项。selection变量应该用“_id=?”来开头,并且selectionArg参数的第一个值应该是这个事件的_ID值。你也能使用没有ID的selection变量来做更新处理。下面的例子更新了用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);  

删除Events表的数据

你能够使用附加在URI上的_ID来删除一个事件,也能够使用标准的选择条件来删除事件。如果使用一个附加的ID,就不能做选择。有两个删除的版本:以应用程序的方式和以同步适配器的方式。应用程序删除时会把“deleted”列设置为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表

CalendarContract.Attendees表的每一行代表一个事件的单一参与者。用给定的EVENT_ID调用query()方法能够这个事件对应的参与者列表。EVENT_ID必须跟一个特殊的事件匹配。

下表列出Attendees表的可写字段,当插入一个新的与会者时,必须包含ATTENDEE_NAME以外的其他所有字段。

常量

描述

EVENT_ID

事件ID

ATTENDEE_NAME

与会者的名字

ATTENDEE_EMAIL

与会者的电子邮件地址

ATTENDEE_RELATIONSHIP

与会者与事件的关系,下列值之一

1. RELATIONSHIP_ATTENDEE

2. RELATIONSHIP_NONE

3. RELATIONSHIP_ORGANIZER

4. RELATIONSHIP_PERFORMER

5. RELATIONSHIP_SPEAKER

ATTENDEE_TYPE

与会者的类型。下列值之一

1. TYPE_REQUIRED

2. TYPE_OPTIONAL

ATTENDEE_STATUS

与会者的与会状态。下列值之一:

1. ATTENDEE_STATUS_ACCEPTED

2. ATTENDEE_STATUS_DECLINED

3. ATTENDEE_STATUS_INVITED

4. ATTENDEE_STATUS_NONE

5. ATTENDEE_STATUS_TENTATIVE

添加与会者

以下是给一个事件添加一个与会者的例子。注意,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表

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

下表列出了Reminders表的可写字段。当插入一个新的提醒时,必须包含所有这些字段。注意,同步适配器在CalendarContract.Calendars表中指定了支持的提醒的类型。详细内容请看ALLOWED_REMINDERS

http://developer.android.com/reference/android/provider/CalendarContract.CalendarColumns.html#ALLOWED_REMINDERS

常量

描述

EVENT_ID

事件的ID

MINUTES

提供应该在几分钟之前触发事件。

METHOD

在服务上设置的报警的方法,下列设置之一:

1. METHOD_ALERT

2. METHOD_DEFAULT

3. METHOD_EMAIL

4. METHOD_SMS

添加提醒

下面的例子给一个事件添加一个提醒,这个体香在事件发生之前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表

CalendarContract.Instances表保存一个事件的开始和结束时间。表中每一行代表一个单一发生的事件。Instances表不是可写的,并且只提供一个查询发生事件的方法。

下表列出了你能够查询的一些字段,注意:时区是由KEY_TIMEZONE_TYPE和KEY_TIMEZONE_INSTANCES字段定义的。

常量

描述

BEGIN

这个事件实例的开始时间。UTC毫秒

END

这个事件实例的结束时间。UTC毫秒

END_DAY

这个事件实例的结束日,相对与日历的时区

END_MINUTE

从日历的时区的0时开始计算的事件实例的结束分钟数

EVENT_ID

这个事件实例的事件ID

START_DAY

相对日历时区的事件实例的开始日

START_MINUTE

相对日历时区的从0时开始计算的实例事件的开始分钟数

查询Instances表

要查询Instances表,你需要在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
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()));    
    }
 }

分享到:
评论

相关推荐

    一个Android日历管理器,提供向系统日历插入日历账户、查询日历账户.zip

    一个Android日历管理器,提供向系统日历插入日历账户、查询日历账户、添加修改删除日历事件以及事件提醒等功能,是时候为你的APP增加一个事件提醒功能啦! 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动...

    Android 日历 年月选择器

    这个“Android日历年月选择器”功能是为了解决这样的需求,它允许用户通过简单的滚动操作来选取年份和月份,而无需打开完整的日历视图。下面将详细介绍如何实现这样一个组件,以及它可能涉及到的关键知识点。 首先...

    Android日历行程.rar

    这个"Android日历行程"的压缩包文件可能包含了关于如何在Android平台上操作和开发日历应用的相关资料,比如`Calendar_01`可能是一个文档或者源代码,详细讲解了Android日历API的使用。 Android的日历API提供了丰富...

    android日历demo

    本示例"android日历DemoCalendar"提供了一个完整的日历应用实例,适用于初学者和开发者学习使用。下面我们将详细探讨这个Demo中涉及的关键知识点。 1. **Android Calendar API**:Android系统提供了Calendar API,...

    Android日历签到

    综上所述,实现“Android日历签到”功能,需要掌握Android日历API的使用,包括获取日历权限、查询日历源、创建和管理日历事件,以及在UI上展示签到信息。通过这一系列步骤,用户就能在自己的Android设备上方便地进行...

    Android日历可左右活动上下定位收缩

    "Android日历可左右活动上下定位收缩"这个项目的核心在于实现一个高度自定义的日历控件,以下将详细解释实现这一功能的关键知识点。 首先,我们需要了解Android的View体系结构。在Android中,自定义视图通常继承自...

    android 日历、日程记录

    下面我们将深入探讨Android日历和日程记录的相关知识点。 一、Android系统日历API Android提供了Calendar Provider API,允许应用访问和修改用户的日历数据。开发者可以通过ContentResolver和Uri对象来操作日历和...

    Android 日历、Android 农历日历 Android 日历节假日

    以下是对标题“Android日历、Android农历日历、Android日历节假日”以及描述中所述知识点的详细阐述。 1. **Android日历API**: Android提供了`android.provider.CalendarContract`类,它是Android系统日历服务的...

    Android日历

    本文将深入探讨Android日历相关的知识点,基于提供的"Android日历"源代码,我们将涵盖以下主题:日历API的使用、日历应用的架构、权限管理、UI设计、事件操作以及如何实现自定义日历视图。 1. **Android日历API**:...

    Android日历+记事本源码

    这个“Android日历+记事本源码”项目,正是实现了这样的功能,它将日历组件与记事本功能巧妙地结合在一起,为用户提供了一个实用的工具。 首先,我们来详细了解一下日历功能的实现。在Android中,日历功能主要通过`...

    android 日历的 demo 项目

    "android 日历的 demo 项目" 提供了一个完整的Android应用程序示例,帮助开发者理解和实现日历相关的功能。以下是对这个项目的详细解读: 1. **日历API**: Android系统提供了`android.app.CalendarContract`类,...

    android 日历控件源码.rar

    "android 日历控件源码.rar"是一个包含Android日历控件源代码的压缩包,用于帮助开发者深入理解日历控件的工作原理,并可以根据需求进行自定义修改。以下是关于Android日历控件的详细知识点: 1. **日历API**:...

    android日历可以安排工作

    "android日历可以安排工作"这一特性,使得用户能够在移动设备上方便地创建、编辑和查看工作相关的日程,提高效率。 首先,Android日历API是开发者用于构建与日历数据交互的应用的重要工具。从Android 1.6(Donut)...

    android谷歌日历源码 android日历源码 android 源码

    1. **Content Provider**:Android日历功能的核心是Content Provider,它负责存储和管理日历数据。开发者可以学习如何创建和维护自定义的Content Providers来扩展或替换系统的日历功能。 2. **数据库操作**:源码...

    android日历的实现

    总之,实现一个Android日历功能涉及多个方面,包括UI布局、日期处理逻辑、事件处理、性能优化和兼容性考虑。通过自定义控件,你可以根据需求打造出独特且功能完善的日历组件。在实际开发过程中,不断调试和优化,...

    自定义实现Android日历

    在Android平台上,自定义日历视图是一种常见的需求,它能够提供更为个性化和功能丰富的用户体验。Caldroid是一个流行的开源库,专为Android设计,用于创建美观且易用的日历组件。通过Caldroid,开发者可以轻松地在...

    android 日历精美控件

    总的来说,"android 日历精美控件"如Caldroid,为Android开发者提供了强大的日历功能和丰富的定制选项,使他们能够快速构建出具有专业级日历功能的应用程序。在实际开发过程中,通过灵活运用Caldroid的API和特性,...

    Android 使用RecycleView打造自定义日历

    最后,`CalendarRecycleView`很可能是一个包含整个日历逻辑的主类或者布局文件,它将RecycleView与适配器、数据源、日历工具类等组件整合在一起,提供了一个完整的日历视图解决方案。 总的来说,通过学习这个项目,...

    android 日历周视图

    在Android平台上,开发一款日历应用并实现类似iOS的日历周视图是一项常见的需求。"android 日历周视图"的实现涉及到多个技术点,包括自定义View、数据管理、事件处理以及用户交互优化。下面将详细介绍这些知识点。 ...

Global site tag (gtag.js) - Google Analytics