如何通过应用程序 ID 而不是事件 ID 数组从设备日历中批量删除事件
How to bulk delete events from the Device calendar by app id, and not by an array of event ids
这是我在我的应用程序中创建日历事件的方式:
for(CalendarEventDescriptor calendarEventDescriptor : calendarEventDescriptors.values()) {
if(calendarEventDescriptor.startMilliseconds>now){
values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, calendarEventDescriptor.startMilliseconds);
values.put(CalendarContract.Events.DTEND, calendarEventDescriptor.endMilliseconds);
values.put(CalendarContract.Events.TITLE, calendarEventDescriptor.title);
values.put(CalendarContract.Events.DESCRIPTION, calendarEventDescriptor.description);
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone);
uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
calendarEventDescriptor.eventId = Long.parseLong(uri.getLastPathSegment());
}
}
在写作的时候,我存储了我创建的所有事件 ID 的数组,这样当用户轻按一个开关时,我循环遍历它们并将它们从日历中删除。
for(long eventId : eventIds) {
if(eventId>0){
Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
rowsDeleted += application.getContentResolver().delete(deleteUri, null, null);
}
}
我想到可以为 CalendarContract.Events.
列之一设置自定义值,这样我就可以一次删除所有事件,但我没有这样做必须记住他们的id(我总是把它们全部删除,从不删除某些)
这可能吗?我应该使用哪个 CalendarContract.Events.
列,然后我该如何删除?
好问题!我同意,在这种情况下,ContentValues
中的 extra-属性 是可行的方法。
我通过重新使用 CalendarContract.Events.CUSTOM_APP_PACKAGE
来完成它,作为对用户不可见的东西,到目前为止,没有发现副作用:
所以我正在像您一样创建活动:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.DTSTART, ...);
values.put(CalendarContract.Events.DTEND, ...);
values.put(CalendarContract.Events.TITLE, ...);
values.put(CalendarContract.Events.DESCRIPTION, ....);
values.put(CalendarContract.Events.CUSTOM_APP_PACKAGE, getApplicationContext().getPackageName());
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
cr.insert(CalendarContract.Events.CONTENT_URI, values);
然后一旦我需要删除所有这些,我调用:
Cursor cursor = cr
.query(CalendarContract.Events.CONTENT_URI,
new String[] { CalendarContract.Events._ID, CalendarContract.Events.CUSTOM_APP_PACKAGE },
null, null, null);
cursor.moveToFirst();
String idsToDelete = "";
for (int i = 0; i < cursor.getCount(); i++) {
// it might be also smart to check CALENDAR_ID here
if (getApplicationContext().getPackageName().equals(cursor.getString(1))) {
idsToDelete += String.format("_ID = %s OR ", cursor.getString(0));
}
cursor.moveToNext();
}
if (idsToDelete.endsWith(" OR ")) {
idsToDelete = idsToDelete.substring(0, idsToDelete.length()-4);
}
cr.delete(CalendarContract.Events.CONTENT_URI, idsToDelete, null);
希望对你有所帮助
您可以使用 ContentProviderOperation with applyBatch 在单个事务中执行多个 deletes/inserts。
检查 this SO answer 代码示例。
经过长时间的研究,我得到了一种新的 google 日历文档
您可以将多个参数添加到一个选择中,这样您就可以找到所有需要的行并一次性删除它们
val operationList = ArrayList<ContentProviderOperation>()
var contentProviderOperation: ContentProviderOperation
appointments.forEach {
contentProviderOperation = ContentProviderOperation
.newDelete(CalendarContract.Events.CONTENT_URI)
.withSelection(CalendarContract.Events.ORIGINAL_SYNC_ID + " =?", arrayOf(it.id))
.build()
operationList.add(contentProviderOperation)
}
contentResolver.applyBatch(CalendarContract.AUTHORITY, operationList)
这是我在我的应用程序中创建日历事件的方式:
for(CalendarEventDescriptor calendarEventDescriptor : calendarEventDescriptors.values()) {
if(calendarEventDescriptor.startMilliseconds>now){
values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, calendarEventDescriptor.startMilliseconds);
values.put(CalendarContract.Events.DTEND, calendarEventDescriptor.endMilliseconds);
values.put(CalendarContract.Events.TITLE, calendarEventDescriptor.title);
values.put(CalendarContract.Events.DESCRIPTION, calendarEventDescriptor.description);
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone);
uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
calendarEventDescriptor.eventId = Long.parseLong(uri.getLastPathSegment());
}
}
在写作的时候,我存储了我创建的所有事件 ID 的数组,这样当用户轻按一个开关时,我循环遍历它们并将它们从日历中删除。
for(long eventId : eventIds) {
if(eventId>0){
Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
rowsDeleted += application.getContentResolver().delete(deleteUri, null, null);
}
}
我想到可以为 CalendarContract.Events.
列之一设置自定义值,这样我就可以一次删除所有事件,但我没有这样做必须记住他们的id(我总是把它们全部删除,从不删除某些)
这可能吗?我应该使用哪个 CalendarContract.Events.
列,然后我该如何删除?
好问题!我同意,在这种情况下,ContentValues
中的 extra-属性 是可行的方法。
我通过重新使用 CalendarContract.Events.CUSTOM_APP_PACKAGE
来完成它,作为对用户不可见的东西,到目前为止,没有发现副作用:
所以我正在像您一样创建活动:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.DTSTART, ...);
values.put(CalendarContract.Events.DTEND, ...);
values.put(CalendarContract.Events.TITLE, ...);
values.put(CalendarContract.Events.DESCRIPTION, ....);
values.put(CalendarContract.Events.CUSTOM_APP_PACKAGE, getApplicationContext().getPackageName());
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
cr.insert(CalendarContract.Events.CONTENT_URI, values);
然后一旦我需要删除所有这些,我调用:
Cursor cursor = cr
.query(CalendarContract.Events.CONTENT_URI,
new String[] { CalendarContract.Events._ID, CalendarContract.Events.CUSTOM_APP_PACKAGE },
null, null, null);
cursor.moveToFirst();
String idsToDelete = "";
for (int i = 0; i < cursor.getCount(); i++) {
// it might be also smart to check CALENDAR_ID here
if (getApplicationContext().getPackageName().equals(cursor.getString(1))) {
idsToDelete += String.format("_ID = %s OR ", cursor.getString(0));
}
cursor.moveToNext();
}
if (idsToDelete.endsWith(" OR ")) {
idsToDelete = idsToDelete.substring(0, idsToDelete.length()-4);
}
cr.delete(CalendarContract.Events.CONTENT_URI, idsToDelete, null);
希望对你有所帮助
您可以使用 ContentProviderOperation with applyBatch 在单个事务中执行多个 deletes/inserts。
检查 this SO answer 代码示例。
经过长时间的研究,我得到了一种新的 google 日历文档 您可以将多个参数添加到一个选择中,这样您就可以找到所有需要的行并一次性删除它们
val operationList = ArrayList<ContentProviderOperation>()
var contentProviderOperation: ContentProviderOperation
appointments.forEach {
contentProviderOperation = ContentProviderOperation
.newDelete(CalendarContract.Events.CONTENT_URI)
.withSelection(CalendarContract.Events.ORIGINAL_SYNC_ID + " =?", arrayOf(it.id))
.build()
operationList.add(contentProviderOperation)
}
contentResolver.applyBatch(CalendarContract.AUTHORITY, operationList)