Android向系統(tǒng)日歷中添加行程

申請(qǐng)動(dòng)態(tài)權(quán)限

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

日歷的content Provider的uri

private static String CALENDER_URL = "content://com.android.calendar/calendars";
private static String CALENDER_EVENT_URL = "content://com.android.calendar/events";
private static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";

添加日歷行程

解題思路:通過(guò)ContentProvider向系統(tǒng)日歷中添加數(shù)據(jù)


日歷提供程序是用戶日歷事件的存儲(chǔ)區(qū)链瓦。您可以利用 Calendar Provider API 對(duì)日歷、事件杰赛、參加者、提醒等執(zhí)行查詢侧甫、插入啥纸、更新和刪除操作。

我們先來(lái)看一下Android jar包有關(guān)于日歷提供的Provider

CalendarContract定義了日歷和日程事件相關(guān)的數(shù)據(jù)模型:


日歷提供程序數(shù)據(jù)模型的圖像化表示
  • CalendarContract.Calendars :此表儲(chǔ)存日歷特定信息赶掖。 此表中的每一行都包含一個(gè)日歷的詳細(xì)信息忿危,例如名稱达箍、顏色、同步信息等铺厨。

  • CalendarContract.Events :此表儲(chǔ)存事件特定信息缎玫。 此表中的每一行都包含一個(gè)事件的信息 — 例如事件標(biāo)題、地點(diǎn)解滓、開始時(shí)間赃磨、結(jié)束時(shí)間等。 事件可一次性發(fā)生洼裤,也可多次重復(fù)發(fā)生邻辉。參加者、提醒和擴(kuò)展屬性存儲(chǔ)在單獨(dú)的表內(nèi)腮鞍。它們各自具有一個(gè) EVENT_ID恩沛,用于引用 Events 表中的 _ID。

  • CalendarContract.Instances : 此表儲(chǔ)存每個(gè)事件實(shí)例的開始時(shí)間和結(jié)束時(shí)間缕减。 此表中的每一行都表示一個(gè)事件實(shí)例。 對(duì)于一次性事件芒珠,實(shí)例與事件為 1:1 映射桥狡。對(duì)于重復(fù)事件,會(huì)自動(dòng)生成多個(gè)行皱卓,分別對(duì)應(yīng)多個(gè)事件實(shí)例裹芝。

  • CalendarContract.Attendees : 此表儲(chǔ)存事件參加者(來(lái)賓)信息。 每一行都表示事件的一位來(lái)賓娜汁。 它指定來(lái)賓的類型以及事件的來(lái)賓出席響應(yīng)嫂易。

  • CalendarContract.Reminders :此表儲(chǔ)存提醒/通知數(shù)據(jù)。 每一行都表示事件的一個(gè)提醒掐禁。一個(gè)事件可以有多個(gè)提醒怜械。 每個(gè)事件的最大提醒數(shù)量在 MAX_REMINDERS 中指定颅和,后者由擁有給定日歷的同步適配器設(shè)置。 提醒以事件發(fā)生前的分鐘數(shù)形式指定缕允,其具有一個(gè)可決定用戶提醒方式的方法峡扩。

Claendar常量:(日歷表)

Calendar的必須添加常量:

  • ACCOUNT_NAME :The account that was used to sync the entry to the device.

  • ACCOUNT_TYPE :The type of the account that was used to sync the entry to the device.

  • NAME:The name of the calendar. Column name.

  • CALENDAR_DISPLAY_NAME :The display name of the calendar. Column name.

  • CALENDAR_COLOR :The color of the calendar. This should only be updated by the sync adapter, not other apps, as changing a calendar's color can adversely affect its display.

  • CALENDAR_ACCESS_LEVEL :The level of access that the user has for the calendar

  • OWNER_ACCOUNT:The owner account for this calendar, based on the calendar feed. This will be different from the _SYNC_ACCOUNT for delegated calendars. Column name.

對(duì)于給定賬戶,只有在同時(shí)指定account_name和account_type時(shí)才能將其視為唯一賬戶障本,account_type字符串對(duì)應(yīng)于AccountManager出注冊(cè)賬戶時(shí)的賬戶驗(yàn)證器教届。

Calendar的建議添加常量:

  • SYNC_EVENTS :Is this calendar synced and are its events stored on the device? 0 - Do not sync this calendar or store events for this calendar. 1 - Sync down events for this calendar.

  • CALENDAR_TIME_ZONE:The time zone the calendar is associated with.

  • ALLOWED_REMINDERS :A comma separated list of reminder methods supported for this calendar in the format "#,#,#".

  • ALLOWED_AVAILABILITY :A comma separated list of availability types supported for this calendar in the format "#,#,#".

  • ALLOWED_ATTENDEE_TYPES :A comma separated list of attendee types supported for this calendar in the format "#,#,#".

Event常量:(事件表,所屬日歷表)
  • CALENDAR_ID:事件所屬日歷的id

  • ORGANIZER:事件組織者(所有者)的電子郵件驾霜。

  • TITLE:事件的標(biāo)題案训。

  • EVENT_LOCATION:事件的發(fā)生地點(diǎn)。

  • DESCRIPTION:事件的描述

  • DTSTART:事件開始時(shí)間粪糙,以從公元紀(jì)年開始計(jì)算的協(xié)調(diào)世界時(shí)毫秒數(shù)表示强霎。

  • DTEND:事件結(jié)束時(shí)間,以從公元紀(jì)年開始計(jì)算的協(xié)調(diào)世界時(shí)毫秒數(shù)表示猜旬。

  • EVENT_TIMEZONE:事件的時(shí)區(qū)脆栋。

  • EVENT_END_TIMEZONE:事件結(jié)束時(shí)間的時(shí)區(qū)。

  • DURATION:RFC5545式的事件持續(xù)時(shí)間洒擦。例如椿争,值為 "PT1H" 表示事件應(yīng)持續(xù)一小時(shí),值為 "P2W" 表示持續(xù) 2 周熟嫩。

  • ALL_DAY:值為 1 表示此事件占用一整天(按照本地時(shí)區(qū)的定義)秦踪。 值為 0 表示它是常規(guī)事件,可在一天內(nèi)的任何時(shí)間開始和結(jié)束掸茅。

  • RRULE: 事件的重復(fù)發(fā)生規(guī)則格式椅邓。例如,"FREQ=WEEKLY;COUNT=10;WKST=SU"昧狮。

  • RDATE:事件的重復(fù)發(fā)生日期,RRULE和RDATE通常聯(lián)合用于定義一組聚合重復(fù)實(shí)例景馁,具體參考RFC5545規(guī)范

  • AVAILABILITY:將此事件視為忙碌時(shí)間還是可調(diào)度的空閑時(shí)間。

  • GUESTS_CAN_MODIFY :來(lái)賓是否可修改事件逗鸣。

  • GUESTS_CAN_INVITE_OTHERS :來(lái)賓是否可邀請(qǐng)其他來(lái)賓合住。

  • GUESTS_CAN_SEE_GUESTS:來(lái)賓是否可查看參加者列表。

Reminder常量 :(提醒表撒璧,所屬事件表)
  • EVENT_ID: 事件id
  • MINUTES: 事件發(fā)生前的分鐘數(shù)透葛,應(yīng)在達(dá)到該時(shí)間時(shí)發(fā)出提醒
  • METHOD: 提醒方式,有:
    METHOD_ALERT, METHOD_DEFAULT,
    METHOD_EMAIL, METHOD_SMS
Instances常量:(實(shí)例表卿樱,所屬事件表僚害,與事件一對(duì)一映射關(guān)系,詳細(xì)解析見上文)
  • BEGIN: 實(shí)例的開始時(shí)間繁调,以協(xié)調(diào)世界時(shí)毫秒數(shù)表示萨蚕。
  • END: 實(shí)例的結(jié)束時(shí)間靶草,以協(xié)調(diào)世界時(shí)毫秒數(shù)表示。
  • START_DAY: 與日歷時(shí)區(qū)相應(yīng)的實(shí)例儒略歷開始日门岔。
  • END_DAY: 與日歷時(shí)區(qū)相應(yīng)的實(shí)例儒略歷結(jié)束日爱致。
  • START_MINUTE: 從日歷時(shí)區(qū)午夜開始計(jì)算的實(shí)例開始時(shí)間(分鐘)。
  • END_MINUTE: 從日歷時(shí)區(qū)午夜開始計(jì)算的實(shí)例結(jié)束時(shí)間(分鐘)寒随。
  • EVENT_ID: 該實(shí)例對(duì)應(yīng)事件的 _ID糠悯。

向系統(tǒng)Calendar中添加Event

public  class CalendarProviderUtil {
    
    // ContentProvider的uri
    private static Uri calendarUri = CalendarContract.Calendars.CONTENT_URI;
    private static Uri eventUri = CalendarContract.Events.CONTENT_URI;
    private static Uri reminderUri = CalendarContract.Reminders.CONTENT_URI;

    private static ContentResolver contentResolver;
    
    /**
     * 檢查是否有日歷表,有返回日歷id,沒(méi)有-1
     * */
    private static int isHaveCalender(){
        // 查詢?nèi)諝v表的cursor
        Cursor cursor = contentResolver.query(calendarUri,null,null,null,null);
        if (cursor == null || cursor.getCount() == 0){
            return -1;
        }else {
            // 如果有日歷表
            try {
                cursor.moveToFirst();
                // 通過(guò)cursor返回日歷表的第一行的屬性值 第一個(gè)日歷的id
                return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID));
            }finally {
                cursor.close();
            }
        }
    }

    /**
     * 添加日歷表
     * */
    private static long addCalendar(){
        // 時(shí)區(qū)
        TimeZone timeZone = TimeZone.getDefault();
        // 配置Calendar
        ContentValues value = new ContentValues();
        value.put(CalendarContract.Calendars.NAME, "我的日歷表");
        value.put(CalendarContract.Calendars.ACCOUNT_NAME, "myAccount");
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, "myType");
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "myDisplayName");
        value.put(CalendarContract.Calendars.VISIBLE, 1);
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
        value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, "myAccount");
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);
        value.put(CalendarContract.CALLER_IS_SYNCADAPTER,true);

        // 插入calendar
        Uri insertCalendarUri = contentResolver.insert(calendarUri,value);

        if (insertCalendarUri == null){
            return -1;
        }else {
            // return Integer.parseInt(insertCalendarUri.toString());
            return ContentUris.parseId(insertCalendarUri);
        }

    }

    /**
     *  添加日歷事件
     * */
    public static void addEvent(Context context){

        // 創(chuàng)建contentResolver
        contentResolver = context.getContentResolver();

        // 日歷表id
        int calendarId = isHaveCalender();
        if (calendarId == -1){
            addCalendar();
            calendarId = isHaveCalender();
        }

        // startMillis
        Calendar beginTime = Calendar.getInstance();
        beginTime.set(2019,8,15);
        long startMillis = beginTime.getTimeInMillis();
 
        // endMillis
        Calendar endTime = Calendar.getInstance();
        endTime.set(2019,8,15);
        long endMillis = endTime.getTimeInMillis();

        // 準(zhǔn)備event
        ContentValues valueEvent = new ContentValues();
        valueEvent.put(CalendarContract.Events.DTSTART,startMillis);
        valueEvent.put(CalendarContract.Events.DTEND,endMillis);
        valueEvent.put(CalendarContract.Events.TITLE,"事件標(biāo)題");
        valueEvent.put(CalendarContract.Events.DESCRIPTION,"事件描述");
        valueEvent.put(CalendarContract.Events.CALENDAR_ID,calendarId);
        valueEvent.put(CalendarContract.Events.EVENT_TIMEZONE,"Asia/Shanghai");

        // 添加event
        Uri insertEventUri = contentResolver.insert(eventUri,valueEvent);
        if (insertEventUri == null){
            Toast.makeText(context,"添加event失敗",Toast.LENGTH_SHORT).show();
        }

        // 添加提醒
        long eventId = ContentUris.parseId(insertEventUri);
        ContentValues valueReminder = new ContentValues();
        valueReminder.put(CalendarContract.Reminders.EVENT_ID,eventId);
        valueReminder.put(CalendarContract.Reminders.MINUTES,15);
        valueReminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALARM);
        Uri insertReminderUri = contentResolver.insert(reminderUri,valueReminder);
        if (insertReminderUri == null){
            Toast.makeText(context,"添加reminder失敗",Toast.LENGTH_SHORT).show();
        }
    }
}

只測(cè)試了一下妻往,有用互艾,可能有bug

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市讯泣,隨后出現(xiàn)的幾起案子纫普,更是在濱河造成了極大的恐慌,老刑警劉巖好渠,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昨稼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拳锚,警方通過(guò)查閱死者的電腦和手機(jī)假栓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)霍掺,“玉大人匾荆,你說(shuō)我怎么就攤上這事「怂福” “怎么了牙丽?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)兔魂。 經(jīng)常有香客問(wèn)我烤芦,道長(zhǎng),這世上最難降的妖魔是什么析校? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任构罗,我火速辦了婚禮,結(jié)果婚禮上勺良,老公的妹妹穿的比我還像新娘。我一直安慰自己骄噪,他們只是感情好尚困,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著链蕊,像睡著了一般事甜。 火紅的嫁衣襯著肌膚如雪谬泌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天逻谦,我揣著相機(jī)與錄音掌实,去河邊找鬼。 笑死邦马,一個(gè)胖子當(dāng)著我的面吹牛贱鼻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滋将,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼邻悬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了随闽?” 一聲冷哼從身側(cè)響起父丰,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掘宪,沒(méi)想到半個(gè)月后蛾扇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魏滚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年镀首,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栏赴。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蘑斧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出须眷,到底是詐尸還是另有隱情竖瘾,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布花颗,位于F島的核電站捕传,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏扩劝。R本人自食惡果不足惜庸论,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棒呛。 院中可真熱鬧聂示,春花似錦、人聲如沸簇秒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至扛禽,卻和暖如春锋边,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背编曼。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工豆巨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掐场。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓往扔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刻肄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓤球,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情況下的生命周期:在用戶參與的情況下...
    AndroidMaster閱讀 3,048評(píng)論 0 8
  • 1 Android四種數(shù)據(jù)持久化方式 Android有四種數(shù)據(jù)持久化方式: SharePreference 輕量...
    Kevin_Junbaozi閱讀 1,207評(píng)論 2 1
  • 由于android系統(tǒng)中應(yīng)用程序之間不能共享內(nèi)存。 因此敏弃,在不同應(yīng)用程序之間交互數(shù)據(jù)(跨進(jìn)程通訊)就稍微麻煩一些卦羡。...
    IT楓閱讀 6,734評(píng)論 0 5
  • 不知道要寫些什么,可是最近負(fù)能量被充的滿滿麦到,一切的無(wú)法觸及绿饵,一切的無(wú)法知曉,一切的無(wú)法了解瓶颠,一切的無(wú)法分享拟赊,...
    24k純逗比閱讀 228評(píng)論 0 0
  • 自從上次和文思見面,易年心里一直沒(méi)有底粹淋,他不知道文思怎么去看待他吸祟。易年從來(lái)沒(méi)有這么喜歡一個(gè)人,所以他很迫...
    晨宇文閱讀 519評(píng)論 0 2