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 ?
You are using System.out.println() which is not supported in android as it has no console so use Logger to get the Log
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