在android中获取联系人非常慢
Posted
技术标签:
【中文标题】在android中获取联系人非常慢【英文标题】:Fetching contacts in android is very slow 【发布时间】: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 后开始工作。有人知道如何在获取联系人期间显示联系人吗?有示例代码吗?
【问题讨论】:
【参考方案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 ,
【讨论】:
以上是关于在android中获取联系人非常慢的主要内容,如果未能解决你的问题,请参考以下文章