[英]Too much time taken to save a contact
我在電話簿中保存了約250個聯系人。 每個聯系人大約需要1秒鍾才能保存到聯系人列表中。 在我的應用程序中,我可能必須保存10,000多個聯系人。 然后將需要幾個小時才能保存它們。 因此,我想要一種快速保存所有聯系人的方法。 您的回答將對我有很大幫助:)
這是我用於for循環以保存聯系人的方法-
public static String saveNewContact(String name, String number, ContentResolver contentResolver){
ContentValues values = new ContentValues();
values.put(Contacts.People.NUMBER, number);
values.put(Contacts.People.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
values.put(Contacts.People.LABEL, name);
values.put(Contacts.People.NAME, name);
Uri dataUri = contentResolver.insert(Contacts.People.CONTENT_URI, values);
Uri updateUri = Uri.withAppendedPath(dataUri, Contacts.People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(Contacts.People.Phones.TYPE, Contacts.People.TYPE_MOBILE);
values.put(Contacts.People.NUMBER, number);
updateUri = contentResolver.insert(updateUri, values);
return getContactID(updateUri, contentResolver);
}
public static String getContactID(Uri contactUri, ContentResolver contentResolver){
String id = "";
Cursor cursor = contentResolver.query(contactUri, null,
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int idx = cursor.getColumnIndex(ContactsContract.Contacts._ID);
id = cursor.getString(idx);
}
return id;
}
編輯-也嘗試過此代碼,但結果相同
ArrayList<ContentProviderOperation> cntProOper = new ArrayList<>();
int contactIndex = cntProOper.size();
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).build());
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, contactIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
.build());
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build()); //Type like HOME, MOBILE etc
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, cntProOper);
} catch (RemoteException | OperationApplicationException exp) {}
好的,這里有很多事情要提...
對於您的第一個代碼,從不使用Contacts.People.XX
API,要認真對待任何地方的任何事物,請確保不要從People
導入任何東西或使用其任何API,這是一個非常老的API,已被棄用了很多年以前,甚至某些設備不支持。
關於您的第二個代碼,很多錯誤和問題,我嘗試在下面的代碼中修復,但特別是出於您的性能要求,請注意,如果要創建許多聯系人,則applyBatch
為每個聯系人都應用applyBatch
一次,可以將許多操作放入ops
ArrayList
並一次性全部應用-更快!
筆記:
ACCOUNT_TYPE
/ ACCOUNT_NAME
值提供與您的應用相關的內容,我已在此代碼中添加了兩個需要定義的const值MY_ACCOUNT_TYPE
/ MY_ACCOUNT_NAME
。 ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
createContact(ops, name, phone);
if (i % 100 == 0) { // experiment with different batch sizes to achieve best performance times
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException | OperationApplicationException e) {
Log.e(TAG, "error applying batch: ", e);
}
ops = new ArrayList<>();
}
}
private void createContact(ArrayList<ContentProviderOperation> ops, String name, String phone) {
ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, MY_ACCOUNT_TYPE)
.withValue(RawContacts.ACCOUNT_NAME, MY_ACCOUNT_NAME).build());
int indexOfRawContactIdOperation = ops.size() - 1;
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, indexOfRawContactIdOperation)
.withValue(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, name)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, indexOfRawContactIdOperation)
.withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, number)
.withValue(Phone.TYPE, Phone.TYPE_MOBILE).build());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.