Android向系统日历中添加日程事件
总结
在项目开发中,我们有预约提醒、定时提醒需求时,可以使用系统日历来辅助提醒;
通过向系统日历中写入事件、设置提醒方式(闹钟),实现到时间自动提醒的功能;
好处:由于提醒功能是交付给系统日历来做,不会出现应用被杀情况,会准时提醒;
坏处:系统日历在提醒时,不能直接再跳转回我们自己的app,只有在提醒文案中加入url,通过调用浏览器来中转;
一般来说实现向系统日历中读写事件:
- 1.需要有读写日历权限
- 2.如果没有日历账户需要先创建账户
- 3.实现日历事件增删改查、提醒功能
申请权限
为了实现在项目中调用系统日历和插入日程事件,我们首先在AndroidManifest.xml文件中添加相关权限,如下:
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
添加日历相关的uri
系统calendar content provider相关的uri,以下为Android2.2版本以后的uri,之前的就不写了
private static String CALANDER_URL = "content://com.android.calendar/calendars";
private static String CALANDER_EVENT_URL = "content://com.android.calendar/events";
private static String CALANDER_REMIDER_URL = "content://com.android.calendar/reminders";
检查并添加日历账户
1.检查是否有现有存在的账户。存在则返回账户id,否则返回-1
private static int checkCalendarAccount(Context context) {
Cursor userCursor = context.getContentResolver().query(Uri.parse(CALANDER_URL), null, null, null, null);
try {
if (userCursor == null)//查询返回空值
return -1;
int count = userCursor.getCount();
if (count > 0) {//存在现有账户,取第一个账户的id返回
userCursor.moveToFirst();
return userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
} else {
return -1;
}
} finally {
if (userCursor != null) {
userCursor.close();
}
}
}
2.添加账户。账户创建成功则返回账户id,否则返回-1
private static String CALENDARS_NAME = "test";
private static String CALENDARS_ACCOUNT_NAME = "test@gmail.com";
private static String CALENDARS_ACCOUNT_TYPE = "com.android.exchange";
private static String CALENDARS_DISPLAY_NAME = "测试账户";
private static long addCalendarAccount(Context context) {
TimeZone timeZone = TimeZone.getDefault();
ContentValues value = new ContentValues();
value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
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, CALENDARS_ACCOUNT_NAME);
value.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 = context.getContentResolver().insert(calendarUri, value);
long id = result == null ? -1 : ContentUris.parseId(result);
return id;
}
3.获取账户。如果账户不存在则先创建账户,账户存在获取账户id;获取账户成功返回账户id,否则返回-1
//检查是否已经添加了日历账户,如果没有添加先添加一个日历账户再查询
private static int checkAndAddCalendarAccount(Context context){
int oldId = checkCalendarAccount(context);
if( oldId >= 0 ){
return oldId;
}else{
long addId = addCalendarAccount(context);
if (addId >= 0) {
return checkCalendarAccount(context);
} else {
return -1;
}
}
}
添加日历事件、日程
public static void addCalendarEvent(Context context,String title, String description, long beginTime){
// 获取日历账户的id
int calId = checkAndAddCalendarAccount(context);
if (calId < 0) {
// 获取账户id失败直接返回,添加日历事件失败
return;
}
ContentValues event = new ContentValues();
event.put("title", title);
event.put("description", description);
// 插入账户的id
event.put("calendar_id", calId);
Calendar mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(beginTime);//设置开始时间
long start = mCalendar.getTime().getTime();
mCalendar.setTimeInMillis(start + ONE_HOUR);//设置终止时间
long end = mCalendar.getTime().getTime();
event.put(CalendarContract.Events.DTSTART, start);
event.put(CalendarContract.Events.DTEND, end);
event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒
event.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Shanghai"); //这个是时区,必须有,
//添加事件
Uri newEvent = context.getContentResolver().insert(Uri.parse(CALANDER_EVENT_URL), event);
if (newEvent == null) {
// 添加日历事件失败直接返回
return;
}
//事件提醒的设定
ContentValues values = new ContentValues();
values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent));
// 提前10分钟有提醒
values.put(CalendarContract.Reminders.MINUTES, 10);
values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
Uri uri = context.getContentResolver().insert(Uri.parse(CALANDER_REMIDER_URL), values);
if(uri == null) {
// 添加闹钟提醒失败直接返回
return;
}
}
删除日历事件、日程
根据设置的title来查找并删除
public static void deleteCalendarEvent(Context context,String title){
Cursor eventCursor = context.getContentResolver().query(Uri.parse(CALANDER_EVENT_URL), null, null, null, null);
try {
if (eventCursor == null)//查询返回空值
return;
if (eventCursor.getCount() > 0) {
//遍历所有事件,找到title跟需要查询的title一样的项
for (eventCursor.moveToFirst(); !eventCursor.isAfterLast(); eventCursor.moveToNext()) {
String eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title"));
if (!TextUtils.isEmpty(title) && title.equals(eventTitle)) {
int id = eventCursor.getInt(eventCursor.getColumnIndex(CalendarContract.Calendars._ID));//取得id
Uri deleteUri = ContentUris.withAppendedId(Uri.parse(CALANDER_EVENT_URL), id);
int rows = context.getContentResolver().delete(deleteUri, null, null);
if (rows == -1) {
//事件删除失败
return;
}
}
}
}
} finally {
if (eventCursor != null) {
eventCursor.close();
}
}
}
至此,我们就能向系统日历中 查找、添加账户,添加、删除、更新日程事件,添加提醒方式,来实现提醒用户的需求。
再次说明一点,当系统日历弹出提醒的时候并不能直接跳转回自己的app,需要在设置description字段的文本中添加一个html,用户点击html时调用浏览器,由页面中转回自己得app。
Android向系统日历中添加日程事件的更多相关文章
- Android 向系统日历中添加事件
查了一天半,总算有点大概了.以下是自己的理解,有错误的地方望指正. android系统有日历功能,应用程序可以根据一些接口开发自己的功能,即使是日历app也是根据这些接口开发的,所以我们可以利用程序向 ...
- Android向系统日历添加日程提醒事件
在项目开发过程中,有时会有预约提醒.定时提醒等需求,这时我们可以使用系统日历来辅助提醒.通过向系统日历中写入事件.设置提醒方式(闹钟),实现到达某个特定的时间自动提醒的功能.这样做的好处是由于提醒功能 ...
- 除了信号触发线程与接收者线程相同的情况能直接调用到slot,其它情况都依赖事件机制(解决上面代码收不到信号的问题其实很简单,在线程的run();函数中添加一个事件循环就可以了,即加入一句exec();),信号槽不就是一个回调函数嘛
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { pThreadCon = new CSerialThread ...
- 【定制Android系统】Android O 在ROM中添加自己的 so 库(1)——Android.mk 与 Android.bp 的区别【转】
本文转载自: 版权声明:本文为博主原创文章,转载时请注明原作者及出处. https://blog.csdn.net/u014248312/article/details/82020204需求:在 ...
- Android 获取系统相册中的所有图片
Android 提供了API可获取到系统相册中的一些信息,主要还是通过ContentProvider 来获取想要的内容. 代码很简单,只要熟悉ContentProvider 就可以了. public ...
- 关于ios苹果系统的中的右键事件,查遍了全网都没有的小技巧。
前阵子公司要求写一套手机端,兼容各种平台和系统,当然,pc端也没有放过. 我用了bootstrap框架和jq.在安卓中的右键事件只需要取消浏览器默认事件,然后长按就可以触发pc端的右键事件,非常好,一 ...
- Android Studio] Gradle项目中添加JNI生成文件(.so文件)
转:http://blog.csdn.net/qiujuer/article/details/24209457 为了适应潮流使用Android Studio还是有半年多了! 对于从Eclipse迁移项 ...
- mfc 小程序---在系统菜单中添加菜单项
1建立一个对话框工程:在dlg类里定义一个菜单指针m_pMenu,在对话框OnInitDialog函数里添加代码: m_pMenu=GetSystemMenu(FALSE);//获取系统菜单的指针 m ...
- Android Tips: 在给drawable中添加图片资源时,文件名必须全小写
在给drawable中添加图片资源时,文件名必须全小写
随机推荐
- 18-09-20 关于Xlwings读写基础1
一 利用xlwings 读取Excel 的读取修改数据 import xlwings as xw""" # 1. 读一个已存在的Excel文件:利用xlwings 读取E ...
- Bitmap每个像素值由指定的掩码决定
bBitmap每个像素值由指定的掩码决定 写了一个小工具来转换Bitmap彩色图片的不同位数. 程序的逻辑是拼接: Bitmap文件头 + Bitmap信息头 + Bitmap数据 在RGB888转换 ...
- keil的可烧写hex文件生成
右键Target1 Options Target for ‘Target1’ ...->Output->Create Executable:->Create HEX File Bui ...
- SVG的用法
三种添加方式 <iframe src="图的地址" frameborder="0"></iframe> <object width ...
- 无法新建EXCLE
Regedit 进入注册表,找到HKEY_CLASSES_ROOT>.xls和.xlsx的ShellNew的值设置为:C:\Windows\ShellNew\EXCEL12.XLSX
- 第四次作业——关于石墨文档(Android)客户端的案例分析
关于石墨文档(Android)客户端的案例分析 作业地址:[https://edu.cnblogs.com/campus/nenu/2016CS/homework/2505] 第一部分调研,评测 1. ...
- 细谈getRequestDispatcher()与sendRedirect()的区别
问题?细谈getRequestDispatcher()与sendRedirect()的区别 首先我们要知道: (1)request.getRequestDispatcher()是请求转发,前后页面共享 ...
- C#通过代码判断并注册程序集到GAC
var dllName = "EasyHook.dll"; var dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirec ...
- PythonStudy——字典的操作 Dictionary operation
dic = {'a': 1, 'b': 2} print(dic) # 增: 字典名[key] = 值 => key已存在就是修改值,不存在就是新增值 dic['c'] = 3 print(di ...
- PythonStudy——逻辑运算符 Logical Operators
在Python中,None.任何数值类型中的0.空字符串“”.空元组().空列表[].空字典{}都被当作False,还有自定义类型,如果实现了 __ nonzero __ () 或 __ len __ ...