【问题标题】:android get contacts detail such as number and thumbnailandroid获取联系人详细信息,例如号码和缩略图
【发布时间】:2015-04-01 19:41:26
【问题描述】:

我使用此代码可以获取联系人的号码和联系人的缩略图,但这不适合并且需要很长时间才能加载和准备联系人。

请帮助我提高此代码的性能:

List<Contact_Pojo> list = new ArrayList<Contact_Pojo>();
ContentResolver cr = getActivity().getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
        null, null, Phone.DISPLAY_NAME + " ASC");

int i = 0;
if (cur.moveToFirst()) {
    while (cur.moveToNext()) {

        Cursor phoneCursor = getActivity()
                .getContentResolver()
                .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER, },
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                + " = ?",
                        new String[] { cur.getString(cur
                                .getColumnIndex(ContactsContract.Contacts._ID)) },
                        null);

        if (phoneCursor.moveToFirst()) {
            Contact_Pojo personContact = new Contact_Pojo();
            /*
             * Id
             */
            personContact.setId(cur.getString(1));
            /*
             * Name
             */
            personContact
                    .setName(cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
            /*
             * Photo ID
             */
            personContact
                    .setImageUrl(cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
            /*
             * Number
             */
            personContact.setNumber(phoneCursor.getString(0));
            //
            list.add(personContact);
        }

        phoneCursor.close();

    }
}

cur.close();
return list;

2015 年 4 月 4 日更新

  • 它很慢,因为它从联系人提供者那里获取了所有列,在这个表中有 +20 列需要很多时间。

【问题讨论】:

    标签: android performance thumbnails android-contentprovider android-contacts


    【解决方案1】:

    如何使用 AsyncTaskLoader,

    当你想获取联系人列表时编写此代码

    getLoaderManager() or getSupportLoaderManager().initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks&lt;D&gt; loadingCallback)

    public class LoadingCallback implements LoaderManager.LoaderCallbacks<Void> {
      @Override
      public Loader<Void> onCreateLoader(int i, Bundle bundle) {
        // Show your dialog;
        return new InitializeContactsTask(context, (ArrayList) contactList, mAdapter);
      }
    
      @Override
      public void onLoadFinished(Loader<Void> voidLoader, Void aVoid) {
        // UI Work here after background task and hide dialog.
      }
    
      @Override
      public void onLoaderReset(Loader<Void> voidLoader) {
      }
    }
    

    public class InitializeApplicationsTask extends AsyncTaskLoader<Void> {
      @Override
      protected void onStartLoading() {
          forceLoad();
      }
    
      @Override
      public Void loadInBackground() {
          // Query the contacts here and return null
    
          return null;
      }
    }
    

    【讨论】:

    • 你能解释更多吗?
    • @adnan9011 你最好阅读this stackoverflow.com/questions/7120813/…
    【解决方案2】:

    这很慢,因为您从联系人提供者那里获取所有列,因此使用投影仅获取那些需要的列。喜欢

    String[] projection = {
    ContactsContract.Contacts.DISPLAY_NAME // this is just example, add fields that required } ;

    你能告诉我第二个查询的目的是什么吗?因为这是我取得联系的结果

    我获得所有联系的方法是

    @SuppressLint("InlinedApi")
        public void readContacts() {
    
            long l1 = System.currentTimeMillis();
    
            Log.d("DEBUG",
                    "starting readContacts() time " + l1);
    
            ContentResolver cr = getContentResolver();
            Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                    null, null, null);
            if (cur.getCount() > 0) {
    
                while (cur.moveToNext()) {
    
                    Contact_pojo cp = new Contact_pojo();
    
                    String Contact_Id = cur.getString(cur
                            .getColumnIndex(ContactsContract.Contacts._ID));
                    String Contact_Name = cur
                            .getString(cur
                                    .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                    String photothumb = "";
                    try {
                        photothumb = cur
                                .getString(cur
                                        .getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
                        if (photothumb != null
                                && !photothumb.toString().equalsIgnoreCase("")) {
                            cp.setImageUri(photothumb);
                        }
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                    cp.setId(Contact_Id);
    
                    cp.setName(Contact_Name);
    
    
    Cursor phones = cr.query(Phone.CONTENT_URI, null,
                        Phone.CONTACT_ID + " = " + Contact_Id, null, null);
                while (phones.moveToNext()) {
                    String number = phones.getString(phones
                            .getColumnIndex(Phone.NUMBER));
                    int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
    
                    Log.d("DEBUG", "number " + number + " type " + type);
                    cp.setNumber(number);
    
                }
                phones.close();
                    contactList.add(cp);
    
                }
            }
            long l2 = System.currentTimeMillis();
            Log.d("DEBUG",
                    "Finished readContacts() time " + l2);
            Log.d("DEBUG","Total contact loaded "+contactList.size()+" within "+ (l2 - l1) + "ms");
    
        }
    

    【讨论】:

    • 是的,你说得对。还有你的另一个建议。请考虑一下,并编辑您的问题以更适合我和其他程序员。
    • 第二个查询准备联系人号码,因为在第一个查询中联系人的号码不存在,只是告诉你联系人有没有电话号码。
    • 不要在安卓虚拟设备中测试这个算法。这个结果在虚拟设备和真实设备之间是不同的。
    • 好的。仅供参考,我在 moto G 设备而非虚拟设备中对其进行了测试。
    • 对不起,是我的错误,当查询号码时,加载所有联系人需要 14 秒
    【解决方案3】:

    不要使用双重查询,如果设备有很多联系人并且它在某些设备上也不起作用,这会花费太多时间......

    您还可以通过单个查询获取联系人..

    使用下面的代码..

    public void fetchContacts() 
        {
    
            String[] projection = new String[] {
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID};
    
    
    
            String _ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
            String DISPLAY_NAME =  Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME;
            String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
    
            Cursor cursor = mActivity.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    projection, ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER + "=?", new String[] { "1" },
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    
            System.out.println("contact size.."+cursor.getCount());
    
            if (cursor.getCount() > 0) {
                while (cursor.moveToNext()) {
    
                    String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));
                    String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));
                    String phoneNumber = cursor.getString(cursor.getColumnIndex(NUMBER));
    
    
    
                    System.out.println(" name : "+name);
                    System.out.println(" number : "+phoneNumber);
    
                }
            }
        }
    

    查看以下链接以获取联系人照片。

    ContactsContract.Contacts.Photo

    Getting a Photo from a Contact

    【讨论】:

    • 很好的答案,但是,为了从联系人获取照片,此代码执行我的代码执行的操作。它是否类似于我的代码? ,因为我使用双重查询,而您的代码使用单一查询来获取姓名和号码以及关于照片,所以您使用另一个查询
    • @adnan9011 我更新了我的答案,请检查它刚刚添加了这一行 String image = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));跨度>
    • 谢谢,让我检查一下。
    • 它不起作用。 cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI) return -1 ,因为ContactsContract.CommonDataKinds.Phone.CONTENT_URI table 上不存在此列
    猜你喜欢
    • 2012-02-21
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2012-01-11
    • 2011-01-13
    相关资源
    最近更新 更多