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

Adding birthday to a contact creates 2 entries after sync

当我尝试为选定的联系人添加生日活动时,我的应用程序出现了一个非常奇怪的问题。 我的代码是:

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”。

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

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

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

每当您进行 ContentResolver.requestSync 调用或自动同步设置为真时,都会调用 onPerformSync。

在执行时,onPerformSync 可以被 Android 中断。如果设备 运行 资源不足或者您的应用不再位于前台,就会发生这种情况。

中断时,Sync Adapter 将停止执行并调用 onSyncCanceled。同步适配器的默认行为是一有机会就重试失败的同步消息。因此,如果您的应用再次设法获取 OS 资源,它将重播中断的同步消息。

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

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

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

在 OnSyncCanceled 中,您可以进行一些简单的检查以确保消息成功,即存在于日历的事件中 table。如果没有,则手动重播它。如果它存在,SyncAdapter 将简单地转到下一条消息,您不会收到任何重复消息。

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

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