javaandroidandroid-contacts

Java app crashes when trying to read contacts from phone


My app crashes when trying to read the contacts. Error message is

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ccoders.contactlistjava/com.ccoders.contactlistjava.MainActivity}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.

I first thought this was a problem of permissions for reading the contacts. But it seems there is something wrong with reading the contacts.

This is the code:

public class MainActivity extends AppCompatActivity {

    // Initialize variable
    RecyclerView recyclerView;
    ArrayList<ContactModel> arrayList = new ArrayList<ContactModel>();
    MainAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        // requesting to the user for permission.

        //checking whether the read contact permission is granted.
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

            System.out.println("Permission is not granted");
            // requesting to the user for permission.
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 100);

        } else {
            System.out.println("Permission is granted");
            //if app already has permission this block will execute.
            getContactList();
        }
    }
    // if the user clicks ALLOW in dialog this method gets called.
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        getContactList();
    }


    private void getContactList() {

        // Initialize uri
        Uri uri = Contacts.CONTENT_URI;

        // Sort by ascending
        String sort = CommonDataKinds.Phone.DISPLAY_NAME+" ASC";

        // Initialize cursor
        Cursor cursor = getContentResolver().query(
                uri, null, null, null, sort
        );

        // Check condition

        if (cursor.getCount() > 0) {
            // When cursor is greater than 0
            // Use while loop

            while(cursor.moveToNext()){
                // Cursor move to next
                // Get contact id

                String id = cursor.getString(cursor.getColumnIndexOrThrow(Contacts._ID));

                // Get contact name

                String name = cursor.getString(cursor.getColumnIndexOrThrow(Contacts.DISPLAY_NAME
                ));
                // Initialze phone uri
                Uri uriPhone = CommonDataKinds.Phone.CONTENT_URI;
                // Initialize selection
                String selection = CommonDataKinds.Phone.CONTACT_ID + " =?";

                // Initialize phone cursor
                Cursor phoneCursor = getContentResolver().query(
                        uriPhone, null, selection, new String[]{id},null
                );
                // Check condition
                if (phoneCursor.moveToNext()){
                    // When phone cursor move to next
                    String number = phoneCursor.getString(phoneCursor.getColumnIndexOrThrow(
                            CommonDataKinds.Phone.NUMBER
                    ));
                    // Initialze contact model
                    ContactModel model = new ContactModel();
                    // Set name
                    model.setName(name);
                    // Set number
                    model.setNumber(number);
                    // Add model in array list
                    arrayList.add(model);
                    // Close phone cursor
                    phoneCursor.close();
                }

                // Close cursor
                cursor.close();
            }

            // Set layout manager
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            // Initialize adapter
            adapter = new MainAdapter(this,arrayList);
            // Set adapter
            recyclerView.setAdapter(adapter);
        }
    }
}

How can I fix this ?


Solution

    1. You are using System.out.println() which is not supported in android as it has no console so use Logger to get the Log

    2. As per the exception you are closing the cursor after reading first data from contact list. So make the cursor.close() out of the while loop