How do I refresh my cursor from another activity?
In my main activity I start a cursor to query phone contacts and display in a listview.
In this main activity I also have a menu, 'Add new Contact', which starts the add new contact activity. A new contact gets added correctly (I can see it in other Contacts apps on my phone), but it is not visible in my listview when the user goes back to main activity.
Is there a way to refresh the cursor from 'add new contact' activity, so the user can see it in the listview when they go back to main activity?
I use AsyncTask in my main activity, if that's any useful info. I read about swapcursor and changecursor but it didn't work when I tried to use them. Here's my 'add new contact' code :
(I call changecursor before the "Contact Saved" toast, but I'm sure it's not done correctly.
package com.example.chris.contactlistcustomlistview;
import android.content.ContentProviderOperation;
import android.content.OperationApplicationException;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.util.ArrayList;
/**
* Created by Chris on 06/05/2016.
*/
public class AddContact extends AppCompatActivity {
EditText nameofcontact;
EditText numberofcontact;
public String contactname;
public String contactnumber;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addcontact);
nameofcontact = (EditText) findViewById(R.id.edittextname);
numberofcontact = (EditText) findViewById(R.id.edittextnumber);
}
public void createButton(View view) {
contactname = nameofcontact.getText().toString();
contactnumber = numberofcontact.getText().toString();
if (contactname.length() == 0) {
Toast.makeText(this, "Please enter a name",
Toast.LENGTH_LONG).show();
return;
}
ArrayList<ContentProviderOperation> contentProviderOperations = new ArrayList<ContentProviderOperation>();
//insert raw contact using RawContacts.CONTENT_URI
contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).build());
//insert contact display name using Data.CONTENT_URI
Log.d("ffff","wwww");
contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,contactname ).build());
//insert mobile number using Data.CONTENT_URI
contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contactnumber).withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build());
try {
//apply the changes
getApplicationContext().getContentResolver().
applyBatch(ContactsContract.AUTHORITY, contentProviderOperations);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
// SelectContactAdapter.changeCursor(cursor);
Toast.makeText(this, "Contact saved",
Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
//This clears the edittext next time user starts the application, rather than
// having the same numbers there, which the user probably doesn't want anymore
protected void onResume() {
final EditText editText = (EditText) findViewById(R.id.edittextname);
super.onResume();
editText.setText("");
}
}
And here's my MainActivity code :
package com.example.chris.contactlistcustomlistview;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MainActivity extends Activity implements PopupMenu.OnMenuItemClickListener {
// ArrayList
ArrayList<SelectContact> selectContacts;
List<SelectContact> temp;
// Contact List
ListView listView;
// Cursor to load contacts list
// Cursor phones, email;
Cursor pCur;
// Pop up
// ContentResolver resolver;
SearchView search;
SelectContactAdapter adapter;
String phoneContactId;
String name;
String phoneNumber;
CharSequence nameofcontact;
// String phoneNumber;
// *****18-04-2016***
Cursor cursor;
ListView mainListView;
ArrayList hashMapsArrayList;
// String contactid;
// *****
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectContacts = new ArrayList<SelectContact>();
// resolver = this.getContentResolver();
listView = (ListView) findViewById(R.id.contacts_list);
LoadContact loadContact = new LoadContact();
loadContact.execute();
search = (SearchView) findViewById(R.id.searchView);
//*** setOnQueryTextListener ***
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
adapter.filter(newText);
return false;
}
});
}
// Load data on background
class LoadContact extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
if (cursor != null) {
cursor.moveToFirst();
}
try {
// get a handle on the Content Resolver, so we can query the provider,
cursor = getApplicationContext().getContentResolver()
// the table to query
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
// Null. This means that we are not making any conditional query into the contacts table.
// Hence, all data is returned into the cursor.
// Projection - the columns you want to query
null,
// Selection - with this you are extracting records with assigned (by you) conditions and rules
null,
// SelectionArgs - This replaces any question marks (?) in the selection string
// if you have something like String[] args = { "first string", "second@string.com" };
null,
// display in ascending order
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
// get the column number of the Contact_ID column, make it an integer.
// I think having it stored as a number makes for faster operations later on.
int Idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
// get the column number of the DISPLAY_NAME column
int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
// get the column number of the NUMBER column
int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
// int photoIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI);
cursor.moveToFirst();
// We make a new Hashset to hold all our contact_ids, including duplicates, if they come up
Set<String> ids = new HashSet<>();
do {
System.out.println("=====>in while");
// get a handle on the contactid, which is a string. Loop through all the contact_ids
String contactid = cursor.getString(Idx);
// if our Hashset doesn't already contain the contactid string,
// then add it to the hashset
if (!ids.contains(contactid)) {
ids.add(contactid);
HashMap<String, String> hashMap = new HashMap<String, String>();
// get a handle on the display name, which is a string
name = cursor.getString(nameIdx);
// get a handle on the phone number, which is a string
phoneNumber = cursor.getString(phoneNumberIdx);
// String image = cursor.getString(photoIdIdx);
// System.out.println("Id--->"+contactid+"Name--->"+name);
System.out.println("Id--->" + contactid + " Name--->" + name);
System.out.println("Id--->" + contactid + " Number--->" + phoneNumber);
SelectContact selectContact = new SelectContact();
// selectContact.setThumb(bit_thumb);
selectContact.setName(name);
selectContact.setPhone(phoneNumber);
// selectContact.setEmail(id);
// selectContact.setCheckedBox(false);
selectContacts.add(selectContact);
}
} while (cursor.moveToNext());
} catch (Exception e) {
e.printStackTrace();
} finally {
// if (cursor != null) {
// }
}
cursor.close();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//into each inflate_listview, put a name and phone number, which are the details making
// our SelectContact, above. And SelectContacts is all these inflate_listviews together
// This is the first property of our SelectContactAdapter, a list
// The next part, MainActivity.this, is our context, which is where we want the list to appear
adapter = new SelectContactAdapter(selectContacts, MainActivity.this);
listView.setAdapter(adapter);
// Select item on listclick
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
nameofcontact = ((TextView)view.findViewById(R.id.name)).getText();
// }
// Creates a new Intent to edit a contact
Intent intent = new Intent(Intent.ACTION_EDIT);
startActivity(intent);
listView.setFastScrollEnabled(true);
}
});
}}
//the is the arrow image, it opens the activity for edit or new contact
public void EditorCreateContact(View v) {
}
@Override
protected void onStop() {
super.onStop();
}
// this is for the settings menu
public void settingsPopUp(View view) {
PopupMenu popup = new PopupMenu(this,view);
popup.setOnMenuItemClickListener(MainActivity.this);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_actions, popup.getMenu());
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
// from the popup_actions.xml, identify the New_contact id and make it
// open the AddContact class
case R.id.New_contact:{
Intent intent = new Intent(this, AddContact.class);
startActivity(intent);
// intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// startActivity(intent);
// finish(); // Call once you redirect to another activity
}
// Toast.makeText(getBaseContext(), "You slected New Contact",Toast.LENGTH_SHORT).show();
//
return true;
}
return false;
}
}