Android联系人筛选:加载带0878/0877/0817前缀的号码
Got it, let's tweak your code to filter only the contacts with those specific prefixes. First, I noticed your current code does two separate database queries (one for lookup keys, then another for each key's phone number) — we can optimize this into a single query to boost performance, while adding the prefix check logic.
Here's the revised code:
private void loadFilteredContacts() { ContentResolver cr = applicationContext.getContentResolver(); // 只查询我们需要的字段:号码(如果需要姓名可以添加DISPLAY_NAME) String[] PROJECTION = { ContactsContract.CommonDataKinds.Phone.NUMBER }; Cursor cursor = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null ); // 防止Cursor为空导致空指针 if (cursor != null) { while (cursor.moveToNext()) { String rawPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); String formattedPhone = Util.formatMSISDN(rawPhone); // 只保留格式化后以目标前缀开头的号码 if (formattedPhone != null) { boolean matchesPrefix = formattedPhone.startsWith("0878") || formattedPhone.startsWith("0877") || formattedPhone.startsWith("0817"); if (matchesPrefix) { contactsSet.add(formattedPhone); } } } cursor.close(); } }
Key changes explained:
- Combined database queries: Your original code fetched lookup keys first, then queried each key individually. This version pulls all phone numbers in one go, cutting down on unnecessary I/O operations and making the code faster.
- Prefix validation: After formatting the number with your existing
Util.formatMSISDNmethod, we check if it starts with any of your target prefixes usingstartsWith(). This ensures we only add matching numbers tocontactsSet. - Null safety: Added a check for
cursor != nullto avoid potential crashes if the query returns no results.
Edge case handling:
If your Util.formatMSISDN method might leave country codes (like +86 or 86) at the start of the number, you'll want to strip those first before checking the prefix. For example:
if (formattedPhone != null) { // Remove common country code prefixes before checking String strippedPhone = formattedPhone.replace("+86", "").replaceFirst("^86", ""); boolean matchesPrefix = strippedPhone.startsWith("0878") || strippedPhone.startsWith("0877") || strippedPhone.startsWith("0817"); if (matchesPrefix) { contactsSet.add(formattedPhone); } }
Quick reminder:
Make sure your app has the READ_CONTACTS permission — on Android 6.0+ (API level 23), you'll need to request this dynamically from the user before running the contact query.
内容的提问来源于stack exchange,提问作者asqa

