如何在诸如WhatsApp android的联系人中显示自定义类型的联系人 [英] How to show custom type contact inside Contact like WhatsApp android
问题描述
/**
* Account type id
*/
public static final String ACCOUNT_TYPE = "com.test.app";
/**
* Account name
*/
public static final String ACCOUNT_NAME = "Test";
public static void addContact(Context context, User contact) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(RawContacts.CONTENT_URI, RawContacts.ACCOUNT_TYPE
+ " = ?", new String[] { AccountConstants.ACCOUNT_TYPE });
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(
RawContacts.CONTENT_URI, true))
.withValue(RawContacts.ACCOUNT_NAME,
AccountConstants.ACCOUNT_NAME)
.withValue(RawContacts.ACCOUNT_TYPE,
AccountConstants.ACCOUNT_TYPE)
// .withValue(RawContacts.SOURCE_ID, 12345)
// .withValue(RawContacts.AGGREGATION_MODE,
// RawContacts.AGGREGATION_MODE_DISABLED)
.build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Settings.CONTENT_URI,
true))
.withValue(RawContacts.ACCOUNT_NAME,
AccountConstants.ACCOUNT_NAME)
.withValue(RawContacts.ACCOUNT_TYPE,
AccountConstants.ACCOUNT_TYPE)
.withValue(Settings.UNGROUPED_VISIBLE, 1).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.GIVEN_NAME, contact.getFullname())
.withValue(StructuredName.FAMILY_NAME, contact.getFullname())
.build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,
contact.getPhoneNumber()).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Email.DATA,
contact.getEmail()).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(Data.MIMETYPE, MIMETYPE)
.withValue(Data.DATA1, contact.getFullname())
.withValue(Data.DATA2, contact.getEmail())
.withValue(Data.DATA3, contact.getHomeAddress()).build());
try {
ContentProviderResult[] results = resolver.applyBatch(
ContactsContract.AUTHORITY, ops);
if (results.length == 0)
AppLog.d(TAG, "Failed to add.");
} catch (Exception e) {
AppLog.e(TAG, e.getMessage(), e);
}
}
问题-当前代码正在添加新联系人,但没有基于电话号码将其合并到现有联系人中.添加联系人之前我有什么需要做的吗?我想在Whats App的联系人"中显示我的应用程序帐户.
Problem - Currently the code is adding new contact but not merging it into existing contact based on Phone number. Is there anything I have to do before adding the contact? I would like to display my app account inside Contact same as Whats App.
我已经实现了SyncService,SyncAdapter,Authenticator,contacts.xml和项目所需的其他类.唯一不起作用的是在默认的联系人"应用程序中显示联系人,而不是创建新的联系人.
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android" >
<ContactsDataKind
android:detailColumn="data2"
android:detailSocialSummary="true"
android:icon="@drawable/ic_launcher"
android:mimeType="vnd.android.cursor.item/com.test.app"
android:summaryColumn="data3" />
</ContactsSource>
推荐答案
我在Android 6.1上遇到了同样的问题,并且据我所知,自Lollipop以来就存在此问题.网络上的每个实现都表明联系人匹配应基于电话号码.它可以在较早的系统上运行-我在KitKat上尝试过,它就像一种魅力.但是由于Android 5.0联系人无法匹配.
I had the same problem on Android 6.1 and as I heard, this issue is present since Lollipop. Every implementation on the web shows that the contact matching should work based on phone number. And it works on earlier systems - I tried it on KitKat and it works like a charm. But since Android 5.0 contacts don't match somehow.
幸运的是,电话号码不是匹配项所依赖的唯一参数-还有显示名.因此,有效的实现应如下所示:
Fortunately phone number is not the only parameter the matching depends on - there is also displayname. So the working implementation should look like this:
// as displayName pass the retrieved ContactsContract.Contacts.DISPLAY_NAME
@Override
public void addContact(@Nonnull final String displayName, @Nonnull final String phone) {
final ContentResolver resolver = context.getContentResolver();
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE,
ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.build());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
.build());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
.build());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, YOUR_MIMETYPE)
.withValue(ContactsContract.Data.DATA1, 12345)
.withValue(ContactsContract.Data.DATA2, "user")
.withValue(ContactsContract.Data.DATA3, "action")
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}
}
如果联系人没有任何显示名,我会留下phoneNumber,那么它至少在早期的Android版本中会匹配.
I left the phoneNumber in case the contact doesn't have any displayname - then it would at least match on earlier Android versions.
这篇关于如何在诸如WhatsApp android的联系人中显示自定义类型的联系人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!