Search code examples
androidandroid-contacts

How do I get more than 500 contact lists on Android?


I want to get more than 500 contact list as string in Android 6.0 and above. Below is a code that works perfectly. But if the contact list is more than 100, the application hangs. I can see people on logcat when I want to get 500 contact list. However, the user cannot do anything in the application. And the application may crash. I think this is related to the forage. I've been dealing with this problem for five days. But I didn't get any performance results. Any help, I'd appreciate it.

My Activity;

public class MainActivity extends Activity {

    Cursor cursor;
    ArrayList<String> vCard;
    String vfile;

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

        vfile = "Contacts" + System.currentTimeMillis() +".vcf";

        getVcardString();
}

private void getVcardString() {

        vCard = new ArrayList<String>();

        cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

        if(cursor!=null&&cursor.getCount()>0){

            cursor.moveToFirst();
            for(int i =0;i<cursor.getCount();i++){


                try {
                    get(cursor);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                cursor.moveToNext();
            }
            cursor.close();
        }
        else{

            ViewAlertDashboard02();
        }

    }

    public void get(Cursor cursor) throws IOException {

        String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);

        AssetFileDescriptor fd = getBaseContext().getContentResolver().openAssetFileDescriptor(uri, "r");
        FileInputStream fis = fd.createInputStream();

        byte[] buf = readBytes(fis);

        try {

            fis.read(buf);

            vcardstring = new String(buf);
            vCard.add(vcardstring);

            Log.d("Vcard",vcardstring);


        } catch (Exception e1){

            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    public byte[] readBytes(InputStream inputStream) throws IOException {
        // this dynamically extends to take the bytes you read
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();

        // this is storage overwritten on each iteration with bytes
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];

        // we need to know how may bytes were read to write them to the byteBuffer
        int len = 0;
        while ((len = inputStream.read(buffer)) != -1) {
            byteBuffer.write(buffer, 0, len);
        }

        // and then we can return your byte array.
        return byteBuffer.toByteArray();
    }
}

My LogCat;

    >     08-17 14:56:44.984 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.024 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.054 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.084 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.124 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.154 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.184 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.204 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.234 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.264 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.284 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.314 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.334 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.364 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.384 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.424 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.454 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.484 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.504 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.534 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.554 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.584 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.604 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.634 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.664 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.684 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.714 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.744 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.764 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.794 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.814 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.844 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.864 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.894 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.924 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.944 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.974 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:45.994 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.024 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.064 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.094 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.134 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.164 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.204 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.264 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.294 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.314 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.334 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.364 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.384 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.404 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.434 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.464 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.484 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.514 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.544 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.564 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.594 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.614 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.644 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.674 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.714 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.744 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.784 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.814 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.844 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.874 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.904 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.924 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.954 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:46.974 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.014 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.044 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.064 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.094 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.114 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.144 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.174 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.204 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.234 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.264 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.284 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.324 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.354 3530-4513/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.394 3530-3548/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.424 3530-13626/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.464 3530-7059/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.494 3530-32650/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.524 3530-4517/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.564 3530-3882/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.594 3530-4755/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.644 3530-3289/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.694 3530-4546/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.724 3530-3293/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.784 3530-3291/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.814 3530-3290/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.854 3530-3292/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.914 3530-26421/? E/VCardComposer: Cursor#moveToNext() returned false
    >     08-17 14:56:47.954 3530-3550/? E/VCardComposer: Cursor#moveToNext() returned false

I have two problems with this code. My first problem is that it doesn't work well and the application may crash. My other problem is that if I have 500 people in my contact list, it shows more. I think the reason for this is that forcing the processor. I think it repeats a process more. Your experience and knowledge can be the solution for me. Thanks in advance.

Note: This code works seamlessly up to 100 contact list on Android 4 and above and supports the latest versions of android. You can use it.


Solution

  • You have two big issues there:

    1. Running long-running code on the UI thread
    2. Mixing between querying over the Phone.CONTENT_URI and the Contacts.CONTENT_URI

    For issue #1, you can change your onCreate code to the following:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        vfile = "Contacts" + System.currentTimeMillis() +".vcf";
    
        new Thread(new Runnable() {
                @Override
                public void run() {
                    getVcardString();
                }
        }).start();
    }
    

    For issue #2, the problem is that your main query is to get all the phones in the DB, and then go phone-by-phone and convert the contact relevant to that phone to a vcard. so if a single contact has multiple phones, you'll be adding the same contact multiple times.

    I'm assuming you need only contacts with phones, so change your main query from:

    cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    

    to:

    String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1";
    cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection, null, null);
    

    If the fixed code still crashes, it might be OutOfMemoryError post the exception stack here, there's some things you can improve.