简体   繁体   中英

Get only numbers shown in the android contactbook

I want to filter what numbers I am getting from Android based on which contacts the user chose to display in his contact book. (For example only contacts saved on the device when all other contacts are excluded)

I read here that you can do this by using Uri queryUri = ContactsContract.Contacts.CONTENT_URI;

I use following code to read the contacts and I allways get every contact, phone, SIM, etc..

    //https://stackoverflow.com/questions/16651609/how-to-display-phone-contacts-only-exclude-sim-contacts
    // http://www.higherpass.com/Android/Tutorials/Working-With-Android-Contacts/1/
    ContentResolver cr = currentActivity.getContentResolver();

    Uri queryUri = ContactsContract.Contacts.CONTENT_URI;
    Cursor cur = cr.query(queryUri,
            null, null, null, null);
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {  //Are there still contacts?
            //See if the contact has at least one number
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {

                String id   = cur.getString( cur.getColumnIndex(ContactsContract.Contacts._ID) );
                String name = cur.getString( cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME) );
                ArrayList<String> numbers = new ArrayList<String>();

                //Read numbers:
                Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                        new String[]{id}, null);
                while (pCur.moveToNext()) {
                   numbers.add( pCur.getString(
                           pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))  );
                   Log.e("Contactbook", "The latest added number is: " + numbers.get(numbers.size()-1) );
                }
                pCur.close();
            }


        }
    }

What am I missing? This code still gives me both SIM and phone contacts to the log.

Edit: To clarifify, in the contactbook you got the "Display options". In there ist the "select contacts to display"-option, and I want to read the contacts that are shown based on the users choice there. So if a user choses to show only SIM-contacts, read only SIM-contacts, if he choses to only show Phone-Contacts, show onyl phone contacts etc...

Try with following "selection".

String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?";

From Android docs:

public static final String IN_VISIBLE_GROUP: An indicator of whether this contact is supposed to be visible in the UI. "1" if the contact has at least one raw contact that belongs to a visible group; "0" otherwise.

This should be your "selection" argument in query API.

Update: I tried below code on Android-2.3(I know it is old device, but right now Don't have newer device with me).

final ContentResolver cr = getContentResolver();
    String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };
    String selection =  ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?" ;
    String[] Args = { "1" };
    final Cursor contacts = cr.query(
                            ContactsContract.Contacts.CONTENT_URI, projection,
                            selection,Args , 
                            null);

This could be a long operation (depending on no. of contacts), hence you should use CursorLoader class (A loader that queries the ContentResolver and returns a Cursor) for this.

cursorLoader.loadInBackground(); 

This will be called on a worker thread to perform the actual load and to return the result of the load operation.

You can easily create two Arrays for each kind of contacts

 ArrayList<String> simContacts = new ArrayList<>();
 //get all sim contacts
Uri simUri = Uri.parse("content://icc/adn");
    Cursor cursorSim = getContext().getContentResolver().query(simUri, null, null, null, null);

    while (cursorSim.moveToNext()) {
        simContacts.add(cursorSim.getString(cursorSim.getColumnIndex("name")));
    } 

}

 ArrayList<String> allContacts = new ArrayList<>(); 
//get all contacts
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);
         if (cursor != null && cursor.getCount() > 0) {
 while (!cursor.isAfterLast()) {

String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
String displayNameColumn = Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME;
                String displayName = cursor.getString(cursor.getColumnIndexOrThrow(displayNameColumn));
//check if simContacts Array contains this particular name
if (!simContacts.contains(displayNameColumn){
allContacts.add(displayNameColumn);
}
 }
}

This is just a working example,of course you can modify to your needs.You can parse more contact fields and make more complication queries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM