1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          Android開發-API指南- Calendar Provider

          來源:互聯網轉載 時間:2023-12-13 10:16:56

          Calendar Provider

          英文原文:http://developer.android.com/guide/topics/providers/calendar-provider.html
          采集日期:2015-05-10

          在本文中

          1. 基礎知識
          2. 用戶權限
          3. 日程表
            1. 查詢日程
            2. 修改日程
            3. 插入日程
          4. events 表
            1. 添加 events 數據
            2. 更新 events 數據
            3. 刪除 events 數據
          5. attendees 表
            1. 添加 attendees 數據
          6. reminders 表
            1. 添加 reminders 數據
          7. instances 表
            1. 查詢 instances 表
          8. 日歷 Intent
            1. 利用 Intent 插入事件
            2. 利用 Intent 編輯事件
            3. 利用 Intent 查看日歷數據
          9. Sync Adapter

          關鍵類

          1. CalendarContract.Calendars
          2. CalendarContract.Events
          3. CalendarContract.Attendees
          4. CalendarContract.Reminders

          Calendar Provider 是用來存放用戶日歷事件(event)的數據庫。 通過 Calendar Provider 的 API ,可以完成對 calendars、events、attendees、reminders 表的查詢、插入、修改和刪除等操作。

          應用程序和 Sync Adapter 都可以使用 Calender Provider API。 對于這兩種不同類型的程序,調用的規則也不一樣。 本文的重點是介紹應用程序是如何使用 Calender Provider API 的。 Sync Adapter 的使用方式會有所不同,請參閱Sync Adapters。

          通常,如果要讀寫日歷數據,應用程序必須在 Manifest 文件中聲明相應的權限,這在用戶權限一節中將會介紹。 為了便于完成一些常見的操作, Calender Provider 提供了一些 Intent,這將在Calendar Intent一節中介紹。 這些 Intent 可以讓用戶打開 Calendar 應用,并完成插入、查看、編輯事件的操作。 用戶在 Calendar 應用中完成交互后,將返回初始的應用中。 這樣發起方應用就不必申請相應權限,也不需要提供瀏覽和創建事件的用戶界面了。

          基礎知識

          Content Provider 負責存放數據并提供數據訪問方式。 Android 系統內置的 Content Provider (包括 Calendar Provider)一般是以關系型數據庫表的形式提供數據的, 行數據代表一條記錄,列數據表示字段類型和意義。 應用程序和 Sync Adapter 通過 Calendar Provider API 來訪問數據庫表中的用戶日歷數據。

          每個 Content Provider 都會公開一個公共的 URI (封裝為一個 Uri 對象),它唯一標識了某部分數據。 如果 Content Provider 管理著多組數據(多張數據表),則各組數據都會有單獨的 URI。 所有用于 Provider 的 URI 都以字符串 “content://” 開頭,表示這些數據是由某個 Content Provider 進行管理的。 Calendar Provider 為其內部類(表)的 URI 定義了很多常量。這些 URI 的格式均為 <class>.CONTENT_URI。比如 Events.CONTENT_URI。

          圖 1 為 Calendar Provider 數據模型的示意圖,給出了主表及與其他表的關聯字段。

          圖 1. Calendar Provider 數據模型

          一個用戶可以擁有多個 Calendar,每個 Calendar 可以與不同類型的帳號關聯(Google Calendar、Exchange 等)。

          CalendarContract 定義了 Calendar 和 Event 的數據模型。這些數據存放在以下數據表中。

          數據表(類) 說明

          CalendarContract.Calendars

          該表存放日程的定義數據。每行表示一條日程的詳細信息,如名稱、顏色、同步信息等。
          CalendarContract.Events 該表存放事件的定義數據。每行表示一個事件,內容包括 — 事件標題、位置、起始時間、結束時間等等。 事件可以是一次性的,也可以重復多次觸發。 參與人員、提醒鬧鐘及附加屬性都存放在其他表中,并通過 EVENT_ID 字段與 Events 表中的 _ID 關聯。
          CalendarContract.Instances 該表存放事件每次觸發時的起始時間和結束時間。一次性事件只會1:1對應一條實例記錄。 對于重復觸發的事件而言,則會自動生成多條實例記錄,對應每一次的觸發。
          CalendarContract.Attendees 該表存放事件的參與人員(來賓)信息。每行代表一位人員。 內容包括人員類型和與會反饋。
          CalendarContract.Reminders 該表存放鬧鐘/通知數據。每行代表一次鬧鐘提醒。 一個事件可以擁有多個鬧鐘提醒。每個事件可擁有的最大提醒數在 MAX_REMINDERS 中定義,這是由擁有該日程的 sync adapter 設置的。 提醒定義了事件觸發前的分鐘數,以及提醒用戶的方式。

          Calendar Provider API 的設計初衷,是既要靈活又要功能強大。另一方面,良好的用戶體驗、保證日程數據的安全也非常重要。 為此,在使用這些 API 時,必須注意以下幾點:

          • 插入、更新和查詢日程事件。 如果要直接插入、修改和查詢 Calendar Provider 中的事件數據,需要獲得合適的權限。 不過,如果還未建立完整的日歷應用或 Sync Adapter,就沒必要申請這些權限。 這時就可以通過 Intent,把讀寫操作交給 Android 內置 Calendar 應用去完成。 在使用這些 Intent 時,用戶會被帶入 Calendar 應用,在預置的表單中進行操作。待操作完畢后,再返回調用方應用。 通過這種調用內置 Calendar 來完成常用操作的方式,可以向用戶提供一種風格統一、容錯性較強的界面。 這也是推薦的訪問方式。詳情請參閱Calendar Intent
          • Sync Adapter。 Sync Adapter 負責將用戶設備上的日程數據與服務器或數據源保持同步。在 CalendarContract.CalendarsCalendarContract.Events 表中,有些字段是留給 Sync Adapter 使用的。 Provider 和應用程序都不要去修改這些字段中的數據。 實際上只有以 Sync Adapter 的方式去訪問時,這些字段才是可見的。 關于 Sync Adapter 的詳細信息,請參閱 Sync Adapter

          用戶權限

          如果要讀取日程數據,應用程序必須在 Manifest 文件中包含 READ_CALENDAR 權限。如果是刪除、插入或修改日程數據,則必須包含 WRITE_CALENDAR 權限:

          <?xml version="1.0" encoding="utf-8"?>
          <manifest xmlns:andro...>
              <uses-sdk android:minSdkVersion="14" />
              <uses-permission android:name="android.permission.READ_CALENDAR" />
              <uses-permission android:name="android.permission.WRITE_CALENDAR" />
              ...
          </manifest>
          

          Calendars 表

          CalendarContract.Calendars 表存放著每項日程的詳細信息。 以下字段均可由應用程序和 Sync Adapter 寫入。 完整的字段清單請參閱手冊 CalendarContract.Calendars

          常量名稱 說明
          NAME 日程的名稱。
          CALENDAR_DISPLAY_NAME 向用戶顯示的日程名稱。
          VISIBLE 布爾值,標明該日程是否可見。 為 0 表示不顯示與該日程關聯的事件,為 1 則表示需要顯示。 該值將會影響 CalendarContract.Instances 表中生成的記錄。
          SYNC_EVENTS 布爾值,標明該日程是否需要同步,及事件是否需要本地保存。 為 0 表示不需要同步或者不保存。為 1 則表示應該同步并在設備中保存事件。

          查詢日程

          以下例子演示了如何讀取某個用戶的日程信息。 為了簡化起見,查詢操作是在用戶界面線程(“主線程”)中進行的。 在實際應用中,這步操作不應放在主線程中,而應該在異步線程中完成。更多信息,請參閱Loaders。 如果不僅要讀取數據,還要修改的話,請參閱 AsyncQueryHandler。

          // 映射數組。為數組建立索引,就不需要動態檢索,以便提高性能。
          public static final String[] EVENT_PROJECTION = new String[] {
              Calendars._ID,                           // 0
              Calendars.ACCOUNT_NAME,                  // 1
              Calendars.CALENDAR_DISPLAY_NAME,         // 2
              Calendars.OWNER_ACCOUNT                  // 3
          };
            
          // 映射數組的索引
          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;
          private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;

          為什么查詢條件中必須包含 ACCOUNT_TYPE字段 ?

          如果要查詢 Calendars.ACCOUNT_NAME 字段,就必須在查詢語句中包含 Calendars.ACCOUNT_TYPE 字段。這是因為 ACCOUNT_NAME 及其 ACCOUNT_TYPE 合在一起才能唯一確定一個賬戶。 ACCOUNT_TYPE 是與認證方式(authenticator)對應的一個字符串,在使用 AccountManager 注冊賬戶時需要用到這個認證方式。 對于那些和賬戶無關的日程,還有一種特殊的賬戶類型,叫做 ACCOUNT_TYPE_LOCAL。 ACCOUNT_TYPE_LOCAL 類型的賬戶不會進行同步。

          接下來就是構建查詢,在查詢語句中指定查詢條件。 這里要查詢的日程,ACCOUNT_NAME為“sampleuser@google.com”, ACCOUNT_TYPE為“com.google”,OWNER_ACCOUNT為“sampleuser@google.com”。 如果要查詢某用戶可查看的所有日程,而不僅限于屬于用戶自己的日程,請去掉OWNER_ACCOUNT條件。 查詢將會返回一個 Cursor 對象,通過該游標可以遍歷返回的結果數據集。 關于 Content Provider 查詢的更多介紹,請參閱 Content Provider。

          // 執行查詢
          Cursor cur = null;
          ContentResolver cr = getContentResolver();
          Uri uri = Calendars.CONTENT_URI;   
          String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 
                                  + Calendars.ACCOUNT_TYPE + " = ?) AND ("
                                  + Calendars.OWNER_ACCOUNT + " = ?))";
          String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google",
                  "sampleuser@gmail.com"}; 
          // 提交查詢并獲取結果 Cursor 對象。
          cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);

          下面通過游標遍歷查詢結果。 這里用到了一開始定義的常量,返回各個字段的數據。

          // 利用游標遍歷結果記錄集
          while (cur.moveToNext()) {
              long calID = 0;
              String displayName = null;
              String accountName = null;
              String ownerName = null;
                
              // 讀取各個字段的數據
              calID = cur.getLong(PROJECTION_ID_INDEX);
              displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
              accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
              ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
                        
              // 用這些數據進行一些操作...
          
             ...
          }
          

          修改日程

          如果要修改日程數據,可以把該項日程的 _ID 作為 URI (withAppendedId()) 的附帶 ID 參數,或者作為第一個查詢條件。 作為查詢條件時,應該以"_id=?"開頭,第一個參數selectionArg應該是該項日程的 _ID。 還可以把 ID 加入 URI 編碼中執行數據更新操作。 以下給出了通過 URI 方式 (withAppendedId()) 修改日程顯示名稱的例子:

          private static final String DEBUG_TAG = "MyActivity";
          ...
          long calID = 2;
          ContentValues values = new ContentValues();
          // 該日程的新名稱
          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);

          插入日程

          日程本來就設計為主要由 Sync Adapter 來維護的,因此只能由一個 Sync Adapter 來插入一項新的日程。 多數情況下,應用程序只能對日程做一些外觀上的修改,比如修改顯示名稱。 如果應用程序需要新建一項日程,可以作為 Sync Adapter 來執行插入操作, ACCOUNT_TYPE 設為 ACCOUNT_TYPE_LOCAL。 ACCOUNT_TYPE_LOCAL 是一種專為日程設計的特殊賬戶,它不與實際的本地賬戶關聯。 這種日程數據也不會與服務器同步。 關于 Sync Adapter 的介紹,請參閱 Sync Adapter。

          Events 表

          CalendarContract.Events 表存放著每個事件的詳細信息。 如果要新增、修改或刪除事件,應用程序必須在 Manifest 文件 中包含 WRITE_CALENDAR 權限。

          以下字段均可由應用程序和 Sync Adapter 寫入。 完整的字段清單,請參閱手冊 CalendarContract.Events。

          常量 說明
          CALENDAR_ID 事件所屬日程的 _ID
          ORGANIZER 日程編制者(所有者)的 Email。
          TITLE 事件標題。
          EVENT_LOCATION 事件所在地。
          DESCRIPTION 事件說明。
          DTSTART 事件起始 UTC 時間,單位為自1970年1月1日以來的毫秒數。
          DTEND 事件結束 UTC 時間,單位為自1970年1月1日以來的毫秒數。
          EVENT_TIMEZONE 事件時區。
          EVENT_END_TIMEZONE 事件結束時間的時區。
          DURATION 事件的持續時間,格式為RFC5545。 比如,"PT1H"表示事件會持續 1 小時,"P2W"則表示持續 2 周。
          ALL_DAY 為 1 表示該事件會占用全天時間,類似于時區設置中的定義。 為 0 表示其為常規事件,可以在一天中的任意時刻開始和結束。
          RRULE 事件重復規則。比如:"FREQ=WEEKLY;COUNT=10;WKST=SU"。 更多示例請查看 RFC5545。
          RDATE 事件重復的日期。通常是把 RDATERRULE 結合起來定義一組重復規則。詳情請參閱 RFC5545 說明。
          AVAILABILITY 標明該事件是在空閑時參與調度,還是在忙時參與。
          GUESTS_CAN_MODIFY 來賓是否可以修改事件。
          GUESTS_CAN_INVITE_OTHERS 來賓是否可以邀請其他人參加。
          GUESTS_CAN_SEE_GUESTS 來賓是否能看到參加人員名單。

          添加事件

          推薦使用 INSERT 來插入一條新的事件,這在 利用 Intent 插入事件 一節中將會介紹。 不過在必要時,也可以直接插入一條事件記錄。本節將介紹這種方式。

          下面列出了插入新事件需要遵守的規則:

          • 必須包含 CALENDAR_IDDTSTART。
          • 必須包含 EVENT_TIMEZONE。 利用 getAvailableIDs() 可以讀取系統已有時區的全部 ID。 請注意,如果是通過 INSERT 來插入事件的,則本條規則不適用。 正如 利用 Intent 插入事件 一節所述,這時會使用默認的時區。
          • 對于那些不需要重復觸發的事件,必須包含 DTEND。
          • 對于要重復發生的事件,必須包含 DURATIONRRULE ,或者是 RDATE。 請注意,如果是通過 INSERT 來插入事件的,則本條規則不適用。 正如 利用 Intent 插入事件 一節所述,這時可使用 RRULEDTSTART 、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);
          
          // 讀取事件 ID,也就是 Uri 的最后一部分
          long eventID = Long.parseLong(uri.getLastPathSegment());
          // 
          // ... 利用 ID 完成一些處理
          //
          //

          注意: 上述例子中,讀取已創建事件 ID 的方式是一種最簡單的方法。 在實際應用中,往往需要利用事件 ID 來對日程進行某些操作 — 比如:添加參與人員、增加事件提醒。

          修改事件

          如果需要讓用戶編輯事件,建議使用 EDIT Intent,這在 利用 Intent 編輯事件 一節中將會介紹。 不過在必要時,也可以直接編輯事件。 在修改事件時,給出事件 _ID 的方式可以是附在 Uri 后面( 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;
          // 新的標題
          values.put(Events.TITLE, "Kickboxing"); 
          updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
          int rows = getContentResolver().update(updateUri, values, null, null);
          Log.i(DEBUG_TAG, "Rows updated: " + rows);  
          

          刪除事件

          可以將 _ID 附在 URI 后面進行刪除操作,也可以用標準的查詢語句來完成。 如果采用前一種方式,就不能再用查詢語句的方式。 刪除操作有兩種版本:作為應用程序、作為 Sync Adapter。 應用程序版本的刪除就是把 deleted 字段置為 1。這會告訴 Sync Adapter 此條記錄已被刪除,同時服務器上也應該完成刪除操作。 Sync Adapter 版本的刪除則會在數據庫中刪除該條事件及所有相關數據。 以下例子演示了應用程序版本的刪除,用到了 _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 必須與事件的實際 _ID一致。

          下表列出了 Attendees 表中可供寫入的字段。在插入新的人員記錄時,必須包含除ATTENDEE_NAME外的所有這些字段。

          常量名稱 說明
          EVENT_ID 事件 ID。
          ATTENDEE_NAME 參加人員的姓名。
          ATTENDEE_EMAIL 參加人員的 Email 地址。
          ATTENDEE_RELATIONSHIP

          該人員與事件的關系??蔀橄铝兄抵唬?/p>

          • RELATIONSHIP_ATTENDEE
          • RELATIONSHIP_NONE
          • RELATIONSHIP_ORGANIZER
          • RELATIONSHIP_PERFORMER
          • RELATIONSHIP_SPEAKER
          ATTENDEE_TYPE

          參加人員的類型??蔀橄铝兄抵唬?/p>

          • TYPE_REQUIRED
          • TYPE_OPTIONAL
          ATTENDEE_STATUS

          參加人員的出席狀況??蔀橄铝兄抵唬?/p>

          • ATTENDEE_STATUS_ACCEPTED
          • ATTENDEE_STATUS_DECLINED
          • ATTENDEE_STATUS_INVITED
          • ATTENDEE_STATUS_NONE
          • 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 表中,定義了 Sync Adapter 支持的提醒類型。 詳情請參閱 ALLOWED_REMINDERS。

          常量名稱 說明
          EVENT_ID 事件 ID。
          MINUTES 在事件發生之前多少分鐘進行提醒。
          METHOD

          提醒方式,這是服務器上的設置??蔀橄铝兄抵唬?/p>

          • METHOD_ALERT
          • METHOD_DEFAULT
          • METHOD_EMAIL
          • 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 是不可寫的,僅用于查詢事件的發生經歷。

          下表列出了 Instances 表中可供查詢的部分字段。 請注意時區是由 KEY_TIMEZONE_TYPEKEY_TIMEZONE_INSTANCES 定義的。

          常量 說明
          BEGIN 事件該次實例的起始時間,單位為 UTC 毫秒數。
          END 事件該次實例的結束時間,單位為 UTC 毫秒數。
          END_DAY 事件該次實例的結束日期,Julian 歷法,并與 Calendar 當前時區相關。
          END_MINUTE 事件該次實例的結束時間,單位是自 Calendar 當前時區 0 點開始的分鐘數。
          EVENT_ID 該次實例的事件 _ID 。
          START_DAY 事件該次實例的開始日期,Julian 歷法,并與 Calendar 當前時區相關。
          START_MINUTE 事件該次實例的開始時間,單位是自 Calendar 當前時區 0 點開始的分鐘數。

          查詢 Instances 表

          如果要查詢 Instances 表,需要在查詢 URI 中指定一個時間范圍。 在以下例子中,通過實現 CalendarContract.EventsColumns 接口, CalendarContract.Instances 讀取了 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
            };
            
          // 為上面的映射數組定義索引常量
          private static final int PROJECTION_ID_INDEX = 0;
          private static final int PROJECTION_BEGIN_INDEX = 1;
          private static final int PROJECTION_TITLE_INDEX = 2;
          ...
          
          // 定義要查詢的事件實例的日期范圍
          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();
          
          // 要在 Instances 表中查詢的事件 ID 
          String selection = Instances.EVENT_ID + " = ?";
          String[] selectionArgs = new String[] {"207"};
          
          // 根據日期范圍構造查詢
          Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
          ContentUris.appendId(builder, startMillis);
          ContentUris.appendId(builder, endMillis);
          
          // 提交查詢
          cur =  cr.query(builder.build(), 
              INSTANCE_PROJECTION, 
              selection, 
              selectionArgs, 
              null);
             
          while (cur.moveToNext()) {
              String title = null;
              long eventID = 0;
              long beginVal = 0;    
              
              // 讀取各字段的值
              eventID = cur.getLong(PROJECTION_ID_INDEX);
              beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
              title = cur.getString(PROJECTION_TITLE_INDEX);
                        
              // 利用這些數據完成一些操作
              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()));    
              }
           }
          

          日程相關的 Intent

          讀寫日程數據時,應用程序并不需要申請權限。 也可以利用 Android 內置 Calendar 應用的 Intent 來完成讀寫操作。 下表列出了 Calendar Provider 支持的 Intent:

          Action URI 說明 附加數據
          VIEW

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

          也可以用 CalendarContract.CONTENT_URI 來引用該 URI。關于該 Intent 的使用實例,請參閱 使用 Intent 查看日程數據。

          打開日歷,時間由<ms_since_epoch>指定。
          VIEW

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

          也可以用 Events.CONTENT_URI 來引用該 URI。關于該 Intent 的使用實例,請參閱 使用 Intent 查看日程數據。

          查看 <event_id> 指定的事件。CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME
          EDITcontent://com.android.calendar/events/<event_id> 也可以用 Events.CONTENT_URI. 來引用該 URI。關于該 Intent 的使用實例,請參閱 使用 Intent 編輯日程數據。編輯 <event_id> 指定的事件。CalendarContract.EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_END_TIME
          EDIT INSERT

          content://com.android.calendar/events

          也可以用 Events.CONTENT_URI 來引用該 URI。關于該 Intent 的使用實例,請參閱 使用 Intent 插入日程數據.

          創建事件。本表后面列出的任何附加數據。

          下表列出了 Calendar Provider 支持的 Intent 附加數據:

          Intent Extra 說明
          Events.TITLE 事件名稱。
          CalendarContract.EXTRA_EVENT_BEGIN_TIME 事件的起始時間,單位是1970年1月1日以來的毫秒數。
          CalendarContract.EXTRA_EVENT_END_TIME 事件的結束時間,單位是1970年1月1日以來的毫秒數。
          CalendarContract.EXTRA_EVENT_ALL_DAY 布爾值,標明事件是否占用一整天。值為truefalse。
          Events.EVENT_LOCATION 事件所在地區。
          Events.DESCRIPTION 事件描述信息。
          Intent.EXTRA_EMAIL 被邀請參加人員的 Email 地址,中間以逗號分隔。
          Events.RRULE 事件重復執行的規則。
          Events.ACCESS_LEVEL 事件是私有的還是公開的。
          Events.AVAILABILITY 事件是在忙時計時,還是空閑時計時。

          下一節將介紹這些 Intent 的使用。

          利用 Intent 插入事件

          利用 INSERT Intent ,應用程序可以將事件插入工作交給 Calendar 來完成。 這樣,就不需要在Manifest 文件中包含 WRITE_CALENDAR 權限。

          當用戶運行這類應用程序時,應用將會向 Calendar 發送 Intent 來完成事件添加操作。 INSERT Intent 利用其附加數據將事件信息填充到 Calendar 的表單中。 然后,用戶可以根據需要取消事件、編輯表單數據,或者把事件保存到日歷中。

          下面給出了一段代碼,在2012年1月1日安排一個事件,時間是上午7:30到8:30。 請留意代碼中的以下內容:

          • Events.CONTENT_URI 定義了 Uri。
          • 用附加字段 CalendarContract.EXTRA_EVENT_BEGIN_TIME and CalendarContract.EXTRA_EVENT_END_TIME 預置了事件的事件。單位必須是 UTC 1970年1月1日以來的毫秒數。
          • 用附加字段 Intent.EXTRA_EMAIL 給出了逗號分割的參加人員列表,形式為 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);
          

          利用 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);

          利用 Intent 查看日程數據

          Calender Provider 提供了兩種方式來使用 VIEW Intent:

          • 以指定日期打開 Calendar 應用
          • 查看事件

          下面的例子演示了以指定日期打開 Calendar 的方式:

          // 日期和時間以1970年1月1日以來的毫秒數給出
          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);
          

          Sync Adapter

          應用程序和 Sync Adapter 在訪問 Calendar Provider 時存在些許微小的差別:

          • Sync Adapter 需要聲明其為 Sync Adapter 身份,把 CALLER_IS_SYNCADAPTER 設為 true 即可。
          • Sync Adapter 需要以 URI 參數的方式指定 ACCOUNT_NAMEACCOUNT_TYPE
          • Sync Adapter 有權限訪問的字段比應用程序或 Widget 都要多一些。 例如,應用程序只能修改日程數據的一些表面性的屬性,諸如名稱、顯示名稱、是否可見、是否需要同步等。 相比之下,Sync Adapter 不僅能訪問這些字段,還能訪問諸如日歷配色、時區、訪問級別、地區等其他很多字段。 當然, Sync Adapter 訪問 ACCOUNT_NAMEACCOUNT_TYPE 是受限的。

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

          關于 Sync Adapter 的實例(與 Calendar 無關),請參閱 SampleSyncAdapter。

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          塌陷命令3D MAX使用步驟?1. 折疊修改器堆棧:包括折疊到或全部折疊?!霸诙褩V姓郫B”的功能是將多個修改器命令轉換為可編輯狀態(可編輯網格、可編輯多邊形或可編輯面片)。因為修改的命令越多,模型就越復雜,3dsmax的運行速度也就越慢。這樣,使用3dsmax可以簡化模型并加快運行速度。缺點:折疊后,無法再更改原始二維圖形和三維幾何圖形的原始參數。2折疊可編輯多邊形:用于多邊形的子對象(僅在“頂點...

          csv文件應該用什么打開?CSV文件本身是一個文本文件,可以被各種文本編輯器打開,如記事本、UE和windows記事本。最廣泛使用的CSV形式是通過特定分隔符以文本形式存儲表數據。這時,使用表格工具,如WPS表格、excel表格打開,向您顯示表格數據。處理CSV文件用什么編輯器比較好?方法如下:1。您可以直接在Excel中編輯,也可以在Excel中保存時選擇CSV格式。2. 如果稍加修改,建議直接...

          OPPOa115與a115k的區別?A115K是A115的升級版,功能和java運行能力都強很多。比如火星文的輸入和顯示,手機內置的QQ2010*/QQ瀏覽器,圖片編輯器,后臺運行Java時支持播放音樂,軟件在線升級,最新固件和搜狗輸入法的集成等等都是A115沒有的。如何區分A115和A115K:手機型號一般會在電池倉或者后蓋上注明。去看看吧。此外,還可以在待機狀態下輸入*#6776#查看手機的所...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>