Android 日曆提供器(二)

來源:互聯網
上載者:User

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()));    
    }
 }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.