添加系统日历事件

前两天,产品提一个需求,说是弄一个系统日历的提醒,到时提醒用户做一些事情,大概这么一个需求。搞了一两天,查看API翻阅文档,算是完成需求了。
这篇文章一个纯粹的代码文章,就是告诉怎么用系统日历添加提醒,跟大家分享一下,以后可以直接拿过来用。
上代码:

CalendarHelper##

package com.example.asia.canlendartest;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;
import java.util.ArrayList;import java.util.TimeZone;

public class CalendarHelper {
    private static final int QUERY = 1;
    private static final int INSERT = 2;
    private Context mContext;
    private MyAsyncQueryHandler mAsyncQueryHandler;
    private ArrayList<String> aList = new ArrayList<String>();
    private int insertCount;//一次性添加日历事件的个数
    private int insertCompleteCount;//当天添加的第几个日历事件
    private OnCalendarQueryCompleteListener onCalendarQueryComplete;
    private ArrayList<String> titleArrayList = new ArrayList<String>();
    private static final String ERROR_PERMISSION = "请到【设置】检查,日历权限是否打开。";
    public CalendarHelper(Context context){
        this.mContext = context;
        mAsyncQueryHandler = new MyAsyncQueryHandler(mContext.getContentResolver());
    } 
   /**
     * 查询添加的日历事件
     * @param titles
     */
    public void queryTitlesEvent(ArrayList<String> titles){
        if(!hasCalendarPermission()){
            Toast.makeText(mContext, ERROR_PERMISSION, Toast.LENGTH_SHORT).show(); 
           return;
        }
        int size = titles.size();
        if(size == 0){
            return;
        }
        Uri eventUri = Uri.parse("content://com.android.calendar/events");
        /*if(Build.VERSION.SDK_INT>=14){
            eventUri =  Events.CONTENT_URI;
        }else {
            eventUri =  Uri.parse("content://com.android.calendar/events");
        }*/
        String[] strs = new String[size];
        //deleted=0表示该日历事件未删除,deleted=1表示该日历事件已删除
        mAsyncQueryHandler.startQuery( QUERY,  null, eventUri, new String[]{"title"}, "title IN ("+getStrAry(size)+")" + " and " + "deleted=0", titles.toArray(strs), null);
    } 
   /**
     *  当查询日历完成后调用,用来看看是否已经成功添加到系统中了
     * @param token
     * @param cookie
     * @param cursor
     */
    private  void  onCalendarQueryComplete(int token, Object cookie, Cursor cursor){
        try{
            while(cursor.moveToNext()){
                aList.add(cursor.getString(cursor.getColumnIndex("title")));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(cursor != null){
                cursor.close();
            }
            if(onCalendarQueryComplete != null ){
                onCalendarQueryComplete.onQueryComplete(aList);
            }
        }
    }
    /**
     * 添加日历事件
     * @param calendarEvents
     * @param onCalendarQueryCompleteListener
     */    public void insertEvent2Calendar(ArrayList<CalendarEvent> calendarEvents, OnCalendarQueryCompleteListener onCalendarQueryCompleteListener){
        if(!hasCalendarPermission()){
            Toast.makeText(mContext, ERROR_PERMISSION, Toast.LENGTH_SHORT).show();
            return;
        }
        this.onCalendarQueryComplete = onCalendarQueryCompleteListener;
        insertCount = calendarEvents.size();
        String eventUriString = "content://com.android.calendar/events";
        for (int i = 0; i < insertCount; i++) { 
           ContentValues values = new ContentValues();
            CalendarEvent c = calendarEvents.get(i); 
           titleArrayList.add(c.getTitleString());
            values.put("calendar_id", 1);
            values.put("title", c.getTitleString()); 
           values.put("description",  c.getDescription()); 
           values.put("dtstart", c.getStartTimeInMillis());
            values.put("dtend", c.getEndTimeInMillis());
            values.put("eventTimezone", TimeZone.getDefault().getID());
            values.put("hasAlarm", 1); 
           try {
                mAsyncQueryHandler.startInsert(c.getMinutes(), c.isNeedReminder(), Uri.parse(eventUriString), values);
            } catch (Exception e) { 
               e.printStackTrace(); 
           }
        } 
   } 
   private void onCalendarInsertComplete(int minutes, Object needRemind, Uri eventUri) {
       insertCompleteCount ++;
        if(eventUri == null){
            if(insertCompleteCount == 1){ 
               Toast.makeText(mContext, ERROR_PERMISSION, Toast.LENGTH_SHORT).show();
            }
            return;
        } 
       if((Boolean)needRemind){
            ContentValues values = new ContentValues();
            String reminderUriString = "content://com.android.calendar/reminders";
            long eventID = Long.parseLong(eventUri.getLastPathSegment()); 
           values.put("event_id", eventID);
            values.put("minutes", minutes);
            values.put("method", 1); 
  

            try {
                mAsyncQueryHandler.startInsert(0, false, Uri.parse(reminderUriString), values);
            } catch (Exception e) {
                e.printStackTrace();
            } 
       } 
       if(insertCompleteCount == insertCount && onCalendarQueryComplete != null){
            queryTitlesEvent(titleArrayList);
        }
    }

    private  class MyAsyncQueryHandler  extends AsyncQueryHandler {
        public MyAsyncQueryHandler(ContentResolver cr) { 
           super(cr);
        }
        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            onCalendarQueryComplete(token, cookie, cursor);
            super.onQueryComplete(token, cookie, cursor);
        }
        @Override
        protected void onInsertComplete(int token, Object cookie, Uri uri) {
            onCalendarInsertComplete(token, cookie, uri);
            super.onInsertComplete(token, cookie, uri);
        }
    }
    public void setOnCalendarQueryComplete(OnCalendarQueryCompleteListener onCalendarQueryComplete){        this.onCalendarQueryComplete = onCalendarQueryComplete;
    }
    public interface OnCalendarQueryCompleteListener{
        void onQueryComplete(ArrayList<String> insertSuccess);
    }
    //String title, String description,  long startTimeInMillis, long endTimeInMillis, Boolean needReminder, Integer minutes    public class CalendarEvent {
        private String titleString;//添加的日历事件名称
        private String description;//日历事件名称的描述
        private long startTimeInMillis;//日历开始时间毫秒值
        private long endTimeInMillis;//日历结束时间毫秒值
        private boolean needReminder;//是否需要闹铃提醒
        private int minutes;//日历开始时间提前多久提醒
        public CalendarEvent(String titleString, String description,
                             long startTimeInMillis, long endTimeInMillis,
                             boolean needReminder, int minutes) {
            super();
            this.titleString = titleString;
            this.description = description;
            this.startTimeInMillis = startTimeInMillis;
            this.endTimeInMillis = endTimeInMillis;
            this.needReminder = needReminder;
            this.minutes = minutes;
        }
        public String getTitleString() { 
           return titleString;
        } 
       public void setTitleString(String titleString) {
            this.titleString = titleString;
        } 
       public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        } 
       public long getStartTimeInMillis() {
            return startTimeInMillis;
        } 
       public void setStartTimeInMillis(long startTimeInMillis) {
            this.startTimeInMillis = startTimeInMillis;
        } 
       public long getEndTimeInMillis() { 
           return endTimeInMillis;
        }
        public void setEndTimeInMillis(long endTimeInMillis) {
            this.endTimeInMillis = endTimeInMillis;
        }
        public boolean isNeedReminder() {
            return needReminder;
        }
        public void setNeedReminder(boolean needReminder) {
            this.needReminder = needReminder;
        }
        public int getMinutes() {
            return minutes;
        }
        public void setMinutes(int minutes) {
            this.minutes = minutes;
        }
   }
    private String getStrAry(int amount){
        String string = "";
        for (int i = 0; i < amount; i++) {
            string = string + ( i== amount-1 ? "?" : "?,");
        }
        return string;
    }
    /**
     * 判断是否提供了修改日历内容的权限
     * @return
     */    private boolean hasCalendarPermission(){
        return PackageManager.PERMISSION_GRANTED == mContext.getPackageManager().checkPermission("android.permission.READ_CALENDAR", mContext.getPackageName());    }}

MainActivity中使用demo

package com.example.asia.canlendartest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;import android.view.View;
import android.widget.Toast;import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public  void insertEvent2Calendar(View view) {
        CalendarHelper calendarHelper = new CalendarHelper(this);
//String title, String description,  long startTimeInMillis, long endTimeInMillis, Boolean needReminder, Integer minutes
        final String title1 = "我是日历标题1";
        final String title2 = "我是日历标题2";
        //创建日历事件1
        CalendarHelper.CalendarEvent calendarEvent1 = calendarHelper.new CalendarEvent(
                title1, 
               "我是日历标题1的详细描述",
                Tools.date2Millis("2017-01-05-09-30-00", "yyyy-MM-dd-HH-mm-ss"), 
               Tools.date2Millis("2017-01-05-19-30-00", "yyyy-MM-dd-HH-mm-ss"),
                true, 0);
        //创建日历事件2
        CalendarHelper.CalendarEvent calendarEvent2 = calendarHelper.new CalendarEvent(
                title2, 
               "我是日历标题2的详细描述",
                Tools.date2Millis("2017-01-05-20-23-00", "yyyy-MM-dd-HH-mm-ss"),
                Tools.date2Millis("2017-01-05-21-10-00", "yyyy-MM-dd-HH-mm-ss"), 
               true, 0);
        ArrayList<CalendarHelper.CalendarEvent> arrayList = new ArrayList<CalendarHelper.CalendarEvent>();
        arrayList.add(calendarEvent1);
        arrayList.add(calendarEvent2);
        //将日历事件添加到系统日历中
        calendarHelper.insertEvent2Calendar(arrayList, new CalendarHelper.OnCalendarQueryCompleteListener() { 
           @Override
            public void onQueryComplete(ArrayList<String> aList) {
                if(aList.contains(title1) || aList.contains(title2)){
                    Toast.makeText(MainActivity.this, "添加日历成功", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "添加日历失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

Tools

public class Tools {
    /**
     * 日期转毫秒
     * @param dateStr
     * @param dateFormat
     * @return
     */
    public static long date2Millis(String dateStr, String dateFormat){ 
       SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        try{
            long millis = sdf.parse(dateStr).getTime();
            return millis;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }
}

反正在我们现在的项目中没有什么问题,不过貌似对某些机型有兼容性问题,大概是测试给我的一个索尼的手机。没办法,舍小家为大家了。那个索尼的兼容性的bug修不好,就搁置了。。其他的手机暂时没发现什么问题。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,085评论 25 707
  • 昨天下班路上,自行车胎突然爆掉了,没办法,只能推着去接娃,然后又推着回家,LG下班就就让他推去修了。知道的家附近...
    云沐妈妈阅读 303评论 0 0
  • “我们分手吧。”她淡淡的说。“你确定?”电话那头他有些不耐烦的反问道。“嗯,确定,分手吧”这次没有参杂一点点情...
    W九阅读 231评论 0 0