美文网首页Android知识总结
ContentProvide管理系统日历

ContentProvide管理系统日历

作者: 已经是咸鱼的小涛orz | 来源:发表于2017-07-12 15:52 被阅读96次

    内容提供者: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一起写。

    相关文章

      网友评论

        本文标题:ContentProvide管理系统日历

        本文链接:https://www.haomeiwen.com/subject/ogsbhxtx.html