我一直在使用Android Calendar Provider来创建本地(非同步)日历,但我最终得到了带有ACCOUNT_TYPE
和ACCOUNT_NAME
的日历。我可以看到它们:
getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, null, CalendarContract.Calendars.ACCOUNT_TYPE + " IS NULL", null, null);
现在我的Google日历应用在启动时崩溃了:(
我尝试使用这段代码删除这些虚拟日历(在成功请求WRITE_CALENDAR
权限后):
getContentResolver().delete(CalendarContract.Calendars.CONTENT_URI, CalendarContract.Calendars.ACCOUNT_TYPE + " IS NULL", null);
但它引发了以下错误
java.lang.IllegalArgumentException:名称不能为空:null 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:165) 在 android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) 在 android.content.ContentProviderProxy.delete(ContentProviderNative.java:544) 在android.content.ContentResolver.delete(ContentResolver.java:1327)
我认为,这是由于他们的帐户类型/名称为空。
你知道如何摆脱它们吗?
注意:Device的Android版本是6.0.1
答案 0 :(得分:1)
以下是发生的事情(请注意所有链接指向5.1.1 CalendarProvider,但可以安全地假设它在Android 6中的工作方式相同):
modifyCalendarSubscription
(无论您如何选择它们)。modifyCalendarSubscription
中,提供商会为每个日历读取ACCOUNT_NAME和ACCOUNT_TYPE列,并尝试创建Account
instance null
,因此在Account
constructor检查null
值时,它会崩溃。这就是你看到的eException实际上被抛出的地方。因此,无论您如何删除日历,它都会在Account
构造函数中失败,因为数据库中的帐户名称为空。
我还没有检查,但您可以使用更新操作覆盖帐户名称和类型。因此,请尝试将其设置为不是null
。
如果这不起作用,您需要root权限才能手动删除日历,或者转到Settings
- > Apps
- > All apps
- > Calendar storage
并清除整个日历数据库(clear data
)。
<强>更新强>
覆盖ACCOUNT_NAME
和ACCOUNT_TYPE
列只有在您设置匹配条件才能通过此行时才会有效:CalendarProvider2.java, line 3989给定该行并且Android中的条件仍然存在6。
它认为如果您不将日历ID附加到Uri
并且您没有按其ID选择日历,它应该有效。因此,让delete
成为update
并将ACCOUNT_NAME
和ACCOUNT_TYPE
重置为非null
的内容应该可以解决问题。
答案 1 :(得分:0)
我有同样的问题。我像这样更新日历行:
private void updateNullAccount() {
String selection = CalendarContract.Calendars.ACCOUNT_NAME + " IS NULL";
Uri uri = CalendarContract.Calendars.CONTENT_URI;
uri = SyncAdapter.asSyncAdapter(uri);
ContentValues values = new ContentValues();
values.put(CalendarContract.Calendars.ACCOUNT_NAME, "NAME BITCH NAME");
values.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
int count = getContentResolver().update(uri, values, selection, null);
count++;
}
我删除了ACCOUNT_NAME后的日历。
创建本地日历时,必须附加查询参数(作为同步适配器,帐户名和帐户类型),并在ContentValues中添加相同的帐户名和帐户类型参数。