【问题标题】:Fetching contacts in android is very slow在android中获取联系人非常慢
【发布时间】:2014-01-21 23:14:20
【问题描述】:

我编写了一个代码来从联系人中获取联系人姓名、电话号码和图像,并将其显示在 android 的列表视图中。它工作正常,但需要更多时间来加载。我曾尝试在代码的某些部分使用多线程。但是加载时间并没有减少。

这里是onCreate() 方法:

protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 lvDetail = (ListView) findViewById(R.id.listView1);

 fetchcontacts();

 lvDetail.setAdapter(new MyBaseAdapter(context, myList));
 }

这里是获取联系人的代码:

  private void fetchcontacts() {

        // TODO Auto-generated method stub
        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
                int count = cursor.getCount();
                if (count > 0) {
                     Toast.makeText(context, "count >0", Toast.LENGTH_SHORT).show();
                    while (cursor.moveToNext()) {
                        String columnId = ContactsContract.Contacts._ID;
                        int cursorIndex = cursor.getColumnIndex(columnId);
                        String id = cursor.getString(cursorIndex);

                      name = cursor.getString(cursor
                .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));


                      Toast.makeText(context, "Toast 1", Toast.LENGTH_SHORT).show();




                        int numCount = Integer.parseInt(cursor.getString(cursor
                            .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
                        if (numCount > 0) {
                             Toast.makeText(context, "Toast 2", Toast.LENGTH_SHORT).show();
                            Cursor phoneCursor = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                                CommonDataKinds.Phone.CONTACT_ID+" = ?", new String[] { id
                }, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

                                while (phoneCursor.moveToNext()) {
                                     Toast.makeText(context, "Toast 3", Toast.LENGTH_SHORT).show();
                              phoneNo = phoneCursor.getString(phoneCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.
                Phone.NUMBER));


                                String image_uri = phoneCursor
                                         .getString(phoneCursor
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));

                             if (image_uri != null) {
                                 Toast.makeText(context, "Toast 4", Toast.LENGTH_SHORT).show();
                                 System.out.println(Uri.parse(image_uri));
                                 try {
                              bitmap = MediaStore.Images.Media
                                 .getBitmap(this.getContentResolver(),
                                 Uri.parse(image_uri));
                                // sb.append("\n Image in Bitmap:" + bitmap);
                                // System.out.println(bitmap);

                                 } catch (FileNotFoundException e) {
                                 // TODO Auto-generated catch block
                                 e.printStackTrace();
                                 } catch (IOException e) {
                                 // TODO Auto-generated catch block
                                 e.printStackTrace();
                                 }

                                 }
                             Toast.makeText(context, name, Toast.LENGTH_SHORT).show();

                                    getDataInList(name,phoneNo,bitmap);
                                 name=null;
                                 phoneNo=null;
                                 Drawable myDrawable = getResources().getDrawable(R.drawable.star1);
                                 bitmap = ((BitmapDrawable) myDrawable).getBitmap();



                                    }
                                    phoneCursor.close();
                                }

                            }


                        }

这里列表视图的 setAdapter() 函数在将所有联系人提取到 ArrayList 后开始工作。有人知道如何在获取联系人期间显示联系人吗?有示例代码吗?

【问题讨论】:

    标签: android contacts android-contacts


    【解决方案1】:

    1.从Cursor 中读取Columns,您只需要,根据您的要求,您只需要_ID,HAS_PHONE_NUMBER,DISPLAY_NAME,因此更改光标读数

    Cursor cursor = getContentResolver().query(
                ContactsContract.Contacts.CONTENT_URI,
                new String[] { ContactsContract.Contacts._ID,
                        ContactsContract.Contacts.HAS_PHONE_NUMBER,
                        ContactsContract.Contacts.DISPLAY_NAME }, null, null,
                ContactsContract.Contacts.DISPLAY_NAME + " ASC");
    

    2.不要在UI线程中做耗时处理..改用AsyncTask

    注意:这两个步骤会在一定程度上解决..但不完全

    【讨论】:

    • 我试过这个。但我没有发现任何明显的变化。在这里,listview 的 setAdapter() 函数在将所有联系人提取到 ArrayList 后开始工作。您知道如何在获取联系人期间显示联系人吗?
    【解决方案2】:

    我通过减少重复查询来做到这一点,这很昂贵。我最好的解决方案是该方法找到每个联系人的所有手机和电子邮件,并插入每个联系人值的列表。现在就像暴风雨一样快:)

    //contact entity
    public class MobileContact {
        public String name;
        public String contact;
        public Type type;
    
        public MobileContact(String contact, Type type) {
            name = "";
            this.contact = contact;
            this.type = type;
        }
    
        public MobileContact(String name, String contact, Type type) {
            this.name = name;
            this.contact = contact;
            this.type = type;
        }
    
        public enum Type {
            EMAIL, PHONE
        }
    
        @Override
        public String toString() {
            return "MobileContact{" +
                    "name='" + name + '\'' +
                    ", contact='" + contact + '\'' +
                    ", type=" + type +
                    '}';
        }
    }
    
    // method for collect contacts
    public List<MobileContact> getAllContacts() {
            log.debug("get all contacts");
            List<MobileContact> mobileContacts = new ArrayList<>();
            ContentResolver contentResolver = context.getContentResolver();
    
            // add all mobiles contact
            Cursor phonesCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.CONTACT_ID}, null, null, null);
            while (phonesCursor != null && phonesCursor.moveToNext()) {
                String contactId = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
                String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "");
                mobileContacts.add(new MobileContact(contactId, phoneNumber, MobileContact.Type.PHONE));
            }
            if (phonesCursor != null) {
                phonesCursor.close();
            }
    
            // add all email contact
            Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Email.DATA, ContactsContract.CommonDataKinds.Email.CONTACT_ID}, null, null, null);
            while (emailCursor != null && emailCursor.moveToNext()) {
                String contactId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID));
                String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                mobileContacts.add(new MobileContact(contactId, email, MobileContact.Type.EMAIL));
            }
            if (emailCursor != null) {
                emailCursor.close();
            }
    
            // get contact name map
            Map<String, String> contactMap = new HashMap<>();
            Cursor contactsCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER}, null, null, ContactsContract.Contacts.DISPLAY_NAME);
            while (contactsCursor != null && contactsCursor.moveToNext()) {
                String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
                String contactName = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                contactMap.put(contactId, contactName);
            }
            if (phonesCursor != null) {
                phonesCursor.close();
            }
    
    
            // replace contactId to display name
            for (MobileContact mobileContact : mobileContacts) {
                String displayName = contactMap.get(mobileContact.name);
                mobileContact.name = displayName != null ? displayName : "";
            }
    
            // sort list by name
            Collections.sort(mobileContacts, new Comparator<MobileContact>() {
                @Override
                public int compare(MobileContact c1, MobileContact c2) {
                    return c1.name.compareTo(c2.name);
                }
            });
    
            return mobileContacts;
        }
    

    【讨论】:

      【解决方案3】:

      大尺寸的联系人用于后台任务。 Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number[i]));

              ContentResolver contentResolver = getContentResolver();
      
              Cursor search = contentResolver.query(uri, new String[]{ContactsContract.PhoneLookup._ID,
                      ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
      
              try {
                  if (search != null && search.getCount() > 0) {
                      search.moveToNext();
                      name = search.getString(search.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                      id = search.getString(search.getColumnIndex(ContactsContract.Data._ID));
                      System.out.println("name" + name + "id" + id);
                 /* tv_name.setText(name);
                  tv_id.setText(id);
                  tv_phone.setText(number);*/
                  }
              } finally {
                  if (search != null) {
                      search.close();
                  }
              }
      

      【讨论】:

        【解决方案4】:

        到目前为止对我来说最快的方式。

        ContentResolver cr = mContext.getContentResolver(); Cursor cursor= mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); if (cursor!= null) { final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); String displayName, number = null, idValue; while (cursor.moveToNext()) {
           displayName = cursor.getString(displayNameIndex);
           idValue= cursor.getString(idIndex);
           Cursor phones  = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null);
           phones.moveToFirst();
           try {
           number = phones.getString(phones.getColumnIndex("data1"));
           }
           catch (CursorIndexOutOfBoundsException e)
           {`
           }
           phones.close();
           userList.add(new ContactModel(displayName , number , null , }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-16
          • 1970-01-01
          • 2013-12-15
          • 1970-01-01
          • 1970-01-01
          • 2016-10-22
          • 2016-10-08
          • 2013-12-16
          相关资源
          最近更新 更多