Android 读取联系人(和详细信息)似乎很慢
Posted
技术标签:
【中文标题】Android 读取联系人(和详细信息)似乎很慢【英文标题】:Android read contacts(and details) seems very slow 【发布时间】:2013-09-13 12:10:13 【问题描述】:我使用以下代码读取每个联系人及其详细信息。
private static final String[] PROJECTION =
Data._ID,
Data.MIMETYPE,
Data.DATA1,
Data.DATA2,
Data.DATA3,
Data.DATA4,
Data.DATA5,
Data.DATA6,
Data.DATA7,
Data.DATA8,
Data.DATA9,
Data.DATA10,
Data.DATA11,
Data.DATA12,
Data.DATA13,
Data.DATA14,
Data.DATA15
;
private static final String SELECTION = Data.LOOKUP_KEY + " = ?";
private String[] mSelectionArgs = "" ;
private static final String SORT_ORDER = Data.MIMETYPE;
private static final int MIME_TYPE_INDEX = 1;
private static final int DISPLAY_NAME_INDEX = 3;//data2
private static final int GIVEN_NAME_INDEX = 3;//data2
private static final int FAMILY_NAME_INDEX = 4;//data3
private static final int MIDDLE_NAME_INDEX = 6;//data5
private static final int ORGANIZATION_INDEX = 2;//data2
private static final int PHONE_TYPE_INDEX = 3;//data2
private static final int PHONE_LABEL_INDEX = 4;//data3
private static final int PHONE_NUMBER_INDEX = 2;//data1
private static final int EMAIL_TYPE_INDEX = 3;//data2
private static final int EMAIL_LABEL_INDEX = 4;//data1
private static final int EMAIL_INDEX = 2;//data1
private byte[] createJsonData(ArrayList<String> selected) throws JSONException, IOException
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
int current = 0;
final String messagePrep = getResources().getString(R.string.progress_message_prep);
final String messageCompress = getResources().getString(R.string.progress_message_compress);
final String messageUpload = getResources().getString(R.string.progress_message_upload);
if(selected == null )
selected = getContacts();
final int count = selected.size();
mHandler.post(new Runnable()
@Override
public void run()
if(mProgressDialog != null)
mProgressDialog.setMax(count);
mProgressDialog.setMessage(messagePrep);
);
updateProgress(current);
JSONObject root = new JSONObject();
JSONArray contactsArray = new JSONArray();
JSONObject contactJSON, phoneJSON, emailJSON;
JSONArray phonesArray,emailsArray;
String name, lastName, middleName,organization;
for (String key : selected)
contactJSON = new JSONObject();
phonesArray = new JSONArray();
emailsArray = new JSONArray();
mSelectionArgs[0] = key;
//Cursor details = managedQuery(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
Cursor details = getApplicationContext().getContentResolver().query(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
//initialize null variables
name = null;
lastName = null;
middleName = null;
organization = null;
while(details.moveToNext())
String mimeType = details.getString(MIME_TYPE_INDEX);
if(mimeType.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE))
name = details.getString(GIVEN_NAME_INDEX);
lastName = details.getString(FAMILY_NAME_INDEX);
middleName = details.getString(MIDDLE_NAME_INDEX);
else if(mimeType.equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE))
organization = details.getString(ORGANIZATION_INDEX);
else if(mimeType.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE))
phoneJSON = new JSONObject();
String phoneNumber = details.getString(PHONE_NUMBER_INDEX);
int type = details.getInt(PHONE_TYPE_INDEX);
String typeLabel = phoneTypeMap.get(String.valueOf(type));
if (typeLabel == null)
typeLabel = details.getString(PHONE_LABEL_INDEX);
phoneJSON.put("ptype", typeLabel);
phoneJSON.put("number", phoneNumber);
phonesArray.put(phoneJSON);
else if(mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE))
emailJSON = new JSONObject();
String email = details.getString(EMAIL_INDEX);
int type = details.getInt(EMAIL_TYPE_INDEX);
String typeLabel = emailTypeMap.get(String.valueOf(type));
if (typeLabel == null)
typeLabel = details.getString(EMAIL_LABEL_INDEX);
emailJSON.put("etype", typeLabel);
emailJSON.put("address",email);
emailsArray.put(emailJSON);
contactJSON.put("firstname", name==null?"null":name);
contactJSON.put("middlename", middleName==null?"null":middleName);
contactJSON.put("lastname", lastName==null?"null":lastName);
contactJSON.put("organization", organization==null?"null":organization);
contactJSON.put("phones", phonesArray);
contactJSON.put("emails", emailsArray);
contactsArray.put(contactJSON);
details.close();
++current;
updateProgress(current);
root.put("contacts", contactsArray);
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
mHandler.post(new Runnable()
@Override
public void run()
if(mProgressDialog != null)
mProgressDialog.setMessage(messageCompress);
);
// to compress
String json_doc = root.toString();
byte[] compressed = compress(json_doc);
mHandler.post(new Runnable()
@Override
public void run()
if(mProgressDialog != null)
mProgressDialog.setMessage(messageUpload);
);
return compressed;
此代码太慢 - 平均每秒读取 3-4 个联系人。这是正常的还是可以优化的?
我认为投影可能是一个很好的优化候选者,但我不确定。
提前致谢。
【问题讨论】:
【参考方案1】:我很难准确地说出您要做什么,但看起来您正在尝试从联系人提供程序读取数据并使用 JSON 将其发送到服务器。我建议您查看 ContactsContract.RawContacts.Entity 表,该表包含您可能正在寻找的所有数据,而无需试图找出您刚刚检索到的 DATA 行的 MIME 类型。通过获取 DATA 行的全部内容,您肯定会减慢您的应用程序的速度。
此外,您应该使用 SyncAdapter 来完成这项工作。见Transferring Data Using Sync Adapters
【讨论】:
嗨,是的,我想做你所说的。但是,不管我是否使用 MIMETYPE 检查,它都会很慢。查询是这里的麻烦部分。【参考方案2】:阅读联系人可以在 2-5 秒内完成。在此处查看示例应用程序
Source code attached
【讨论】:
在 GitHub 上添加指向您的代码的直接链接怎么样,或者直接在此处添加更好?我下载那个应用程序只是因为我从屏幕上看到有 GitHub 链接,看看你是如何在 2-5 秒内完成它的。该应用程序在启动时崩溃。由于这些原因,我认为这个答案没有帮助以上是关于Android 读取联系人(和详细信息)似乎很慢的主要内容,如果未能解决你的问题,请参考以下文章
Android:在 Contact Uri 列表中显示所有有电话号码的联系人详细信息