为联系人添加生日会在同步后创建2个条目

时间:2018-07-10 14:25:44

标签: android android-contacts

当我尝试在选择的联系人上添加生日事件时,我的应用出现了一个非常奇怪的问题。 我的代码是:

int mret = np2.getValue()+1;
ContentResolver cr = v.getContext().getContentResolver();

ContentValues values = new ContentValues();
values.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
values.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
if (boolyear == true) {
    values.put(ContactsContract.CommonDataKinds.Event.START_DATE, np3.getValue() + "-" + mret + "-" + np1.getValue());
} else {
    values.put(ContactsContract.CommonDataKinds.Event.START_DATE, "0000-" + mret + "-" + np1.getValue());
}
Uri bduri= null;
try {
    bduri= cr.insert(ContactsContract.Data.CONTENT_URI,values);
} catch (Exception e) {}

上面的代码在创建生日事件时工作正常,但是几秒钟后出现了第二个生日条目,这可能是同步的结果,因为只有在有Internet连接时才会发生。

这不是设备的问题,因为从Play商店下载的其他应用可以正常运行。只是我的应用创建了两次生日条目。

为什么会发生这种情况以及如何解决? 预先谢谢你。


更新:我设法修复了它。问题是日期格式。所有值(日和月)必须为两位数格式。例如。 “ 1980-07-01”,而不是“ 1980-7-1”。

2 个答案:

答案 0 :(得分:1)

我设法解决了。问题是日期格式。所有值(日和月)必须为两位数格式。例如。 “ 1980-07-01”,而不是“ 1980-7-1”。

答案 1 :(得分:0)

我假设您正在使用同步适配器与日历进行交互。

同步适配器有两种重要方法:

onPerformSync(...)和onSyncCanceled(...)

每当您调用ContentResolver.requestSync或自动同步设置为true时,都会调用

onPerformSync。

在执行时,Android可以中断onPerformSync。如果设备的资源不足或应用程序不在前台,则会发生这种情况。

在中断时,同步适配器将在其所在位置停止执行,并调用onSyncCanceled。同步适配器的默认行为是在第一次获得失败的同步消息后重试失败的同步消息。因此,如果您的应用设法再次获取操作系统资源,它将重播中断的同步消息。

您的某些消息可能已被完全处理,并且在onPerformSync即将完成之前,同步适配器已中断。此时,您设法保存了事件,但是,同步适配器认为同步失败,因此,下次尝试同步时,它将再次重播相同的消息。

我不确定您一次是否同步一个事件,因此我无法提供确定的解决方案。但是,您可以做的是更改同步适配器的默认行为,以阻止其重播“失败”消息。

Bundle extras = new Bundle();
...
extras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
CalendarConstants.AUTHORITY, true);
ContentResolver.requestSync(mAccount, CalendarConstants.AUTHORITY, extras);

在OnSyncCanceled中,您可以进行一些小检查以确保消息成功,即日历的事件表中存在该消息。如果没有,请手动重播。如果存在,则SyncAdapter会继续前进到下一条消息,并且您不会得到任何重复。

或者,您可以确保onPerformSync中的所有操作都是原子操作。