簡體   English   中英

保存聯系人花費了太多時間

[英]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並一次性全部應用-更快!

筆記:

  1. 這應該為您增加100倍的緩存大小,使緩存大小增加100倍,但是您可以使用該數字,只是請注意,如果該數字太大,則可能會冒一些Java警告“ Transaction Too Large”,並且該批處理將失敗。
  2. 始終為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM