我的应用程序必须更新给定联系人的组织属性。如果联系人已经有一个已填写的组织属性,则此操作可以正常工作,但如果组织标签为空,则返回NullPointerException。
public boolean updateOrganizationFromContact(String contactId, String companyName){
//Get contact from ContactList
boolean foundContact = false;
int i = -1;
while(!foundContact && i<contactList.size()){
i++;
foundItem = contactId.equals(contactList.get(i).getId());
}
//Check if Contact has already a filled up organization-tag
if (contactList.get(i).getOrganization().hasEntry()){
//if yes, update:
ContentResolver contentResolver = context.getContentResolver();
String where = ContactsContract.Data.CONTACT_ID + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ?";
String[] whereParameters = new String[]{contactId,
ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE};
ContentValues values = new ContentValues();
values.put(ContactsContract.CommonDataKinds.Organization.DATA, companyName);
contentResolver.update(ContactsContract.Data.CONTENT_URI, values, where, whereParameters);
return true;
} else {
//if not, go to next method:
return createOrganizationFromContact(contactId, companyName);
}
}
private boolean createOrganizationFromContact(String contactId, String companyName) {
ContentResolver contentResolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.CONTACT_ID, contactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Organization.DATA, companyName);
//now this is the line with the NPE (line 212):
Uri uri = contentResolver.insert(ContactsContract.Data.CONTENT_URI, values);
return true;
}
生成的Stacktrace:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/1229i......... flg=0x1 }}
to activity {Activity}: java.lang.NullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:3319)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3362)
at android.app.ActivityThread.access$1100(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1431)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:420)
at android.content.ContentResolver.insert(ContentResolver.java:866)
at de.MYAPPLICTION.dienstleistung.objects.ContactAPI.ContactInformationSingleton.createOrganizationFromContact(ContactInformationSingleton.java:212)
at de.MYAPPLICTION.dienstleistung.objects.ContactAPI.ContactInformationSingleton.updateOrganizationFromContact(ContactInformationSingleton.java:202)
at de.MYAPPLICTION.fragments.client.NewClientActivity.addContactToClient(NewClientActivity.java:282)
at de.MYAPPLICTION.dienstleistung.fragments.client.NewClientActivity.onActivityResult(NewClientActivity.java:274)
at android.app.Activity.dispatchActivityResult(Activity.java:5293)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
... 11 more
我认为有一些ContentValues缺失。但是我找不到更新联系人组织的任何文档/示例。任何帮助吗?
我发现我对RawContacts的理解不太好。您必须首先创建RawContact,然后添加引用它的数据。要将新的RawContact链接到现有的RawContact,需要一个像DisplayName这样的Datafiled。ContactsApp会自动完成映射,但你必须信任它。
这就是解决方案,灵感来自Android样本中的ContactsManager应用程序
private boolean createOrganizationFromContact(Contact contact, String companyName) {
try {
ContentResolver contentResolver = context.getContentResolver();
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
operations.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, context.getResources().getString(R.string.accounttype))
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, context.getResources().getString(R.string.accountusername))
.build());
operations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Organization.DATA, companyName)
.build());
operations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getDisplayName())
.build());
contentResolver.applyBatch(ContactsContract.AUTHORITY, operations);
} catch (RemoteException e) {
e.printStackTrace();
return false;
} catch (OperationApplicationException e) {
e.printStackTrace();
return false;
}
return true;
}
}