ContentProvide管理系统日历

内容提供者:ContentProvide, 是不同应用程序间进行数据交换的标准API,以URL形式对外提供数据接口;
内容解析者:ContentResolver,根据URL 访问操作ContentProvide接口。

申请权限

需要对日历进行增删改查操作,因此需要在manifest中添加相应的读写权限

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

配置相关的Url

也就是系统日历Calendar Provide的对外接口,下面的是2.2之后的Url,2.2之前又是一套
反正项目最低版本都远大于2.2,就不写了-。-

private final String CALANDER_URL = "content://com.android.calendar/calendars";  //  日历账户
private final String CALANDER_EVENT_URL = "content://com.android.calendar/events";  //  日历事件
private final String CALANDER_REMIDER_URL = "content://com.android.calendar/reminders";  //  日历提醒

获取日历账户

一般来说各大厂商的手机都会预设一个叫手机的日历账户 如果不是就不是吧,我这一打测试机都叫这个我也没办法不系orz
当然也不排除有的手机没有预设的日历账户,比如ASUS Nexus 7,这个时候就需要开发者添加一个账户
Tips: 创建账户所添加的日程,当创建这个账户的APP重新安装的时候,添加的日程就全没了,目前还不清楚什么原因,还是太菜鸡 囧rz

  1. 获取账户。返回值为-1表示当前没有日历账户
    private int getSystemCalendarAccount(){
        int account = -1;
        Cursor userCursor =  null;
        try {
            userCursor = mContext.getContentResolver().query(Uri.parse(CALANDER_URL), null, null, null, null);
            if (userCursor != null && userCursor.getCount() > 0){
                userCursor.moveToFirst();
                account = userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (userCursor != null) {
                userCursor.close();
            }
        }
        return account;
    }
  1. 新增一个账户。返回值为新增账户的id,-1表示创建失败
private long setFoowwCalendar(){
        ContentValues contentValues = new ContentValues();
        //  日历名称
        contentValues.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
        //  日历账号,为邮箱格式
        contentValues.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
        //  账户类型,com.android.exchange
        contentValues.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
        //  展示给用户的日历名称
        contentValues.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
        //  它是一个表示被选中日历是否要被展示的值。
        //  0值表示关联这个日历的事件不应该展示出来。
        //  而1值则表示关联这个日历的事件应该被展示出来。
        //  这个值会影响CalendarContract.instances表中的生成行。
        contentValues.put(CalendarContract.Calendars.VISIBLE, 1);
        //  账户标记颜色
        contentValues.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
        //  账户级别
        contentValues.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        //  它是一个表示日历是否应该被同步和是否应该把它的事件保存到设备上的值。
        //  0值表示不要同步这个日历或者不要把它的事件存储到设备上。
        //  1值则表示要同步这个日历的事件并把它的事件储存到设备上。
        contentValues.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
        //  时区
        contentValues.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone.getDefault().getID());
        //  账户拥有者
        contentValues.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
        contentValues.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);

        Uri calendarUri = Uri.parse(CALANDER_URL);
        calendarUri = calendarUri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
                .build();

        Uri result = mContext.getContentResolver().insert(calendarUri, contentValues);
        return result == null ? -1 : ContentUris.parseId(result);
    }
  1. 联合1、2,检查&创建&获取账户
    private int getAccount() {
        int account = -1;
        account = getSystemCalendarAccount();
        if (account < 0){
            return (int)setFoowwCalendar();
        }
        return account;
    }

创建日历事件

下面的 Schedule 是自定义的日程信息类

private Uri addCalendarEvent(Schedule schedule){
        int account = getAccount();
        if (account < 0)
            return null;
        ContentValues contentValues = new ContentValues();
        // 事件的日历_ID。
        contentValues.put(CalendarContract.Events.CALENDAR_ID, account);
        //  事件标题
        contentValues.put(CalendarContract.Events.TITLE, schedule.getTitle());
        //  事件发生的地点
        contentValues.put(CalendarContract.Events.EVENT_LOCATION, schedule.getLocation());
        //  事件描述
        contentValues.put(CalendarContract.Events.DESCRIPTION, schedule.getDescription());
        //  事件开始时间
        contentValues.put(CalendarContract.Events.DTSTART, schedule.getStartTime());
        //  事件结束时间
        contentValues.put(CalendarContract.Events.DTEND, schedule.getEndTime());
        //  设置有闹钟提醒
        contentValues.put(CalendarContract.Events.HAS_ALARM, 1);
        //  事件时区
        contentValues.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
        //  返回事件
        return mContext.getContentResolver().insert(Uri.parse(CALANDER_EVENT_URL), contentValues);
    }

创建日历提醒

日历提醒是基于日历事件的,因此需要事件的url

private Uri addCalendarAlarm(Uri event){
        //  事件提醒的设定
        ContentValues contentValues = new ContentValues();
        //  事件的ID
        contentValues.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(event));
        //  准时提醒    提前0分钟提醒
        contentValues.put(CalendarContract.Reminders.MINUTES, 0);
        contentValues.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
        return mContext.getContentResolver().insert(Uri.parse(CALANDER_REMIDER_URL), contentValues);
    }

添加日程

在获取或者创建 账户,创建事件及事件提醒之后,就可以把日程添加到日历中
如果添加失败,还可以通过Intent打开日历的添加界面让用户手动添加

    public void insert(Schedule schedule){
        try {
            addCalendarAlarm(addCalendarEvent(schedule));
        }catch (Exception e){
            e.printStackTrace();
            Intent intent = new Intent(Intent.ACTION_INSERT)
                    .setData(CalendarContract.Events.CONTENT_URI)
                    .putExtra(CalendarContract.Events.TITLE, schedule.getTitle())
                    .putExtra(CalendarContract.Events.DESCRIPTION, schedule.getDescription())
                    .putExtra(CalendarContract.Events.EVENT_LOCATION, schedule.getLocation())
                    .putExtra(CalendarContract.Events.DTSTART, schedule.getStartTime())
                    .putExtra(CalendarContract.Events.DTEND, schedule.getEndTime())
                    .putExtra(CalendarContract.Reminders.MINUTES, 0);
            mContext.startActivity(intent);
        }
    }

结语

今天就先这样把,剩下的删除、修改、查询之后和ContentResolver一起写。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容