I have created an app in which I am getting the contacts from a device.
But I want to remove the duplicate contacts from the results.
How could I do it?
MainActivity
public class MainActivity extends Activity implements OnItemClickListener {
EditText searchText;
ArrayList<String> phno0 = new ArrayList<String>();
List<String> arrayListNames;
public List<ProfileBean> list;
public SearchableAdapter adapter;
//ProfileBean bean;
String[] cellArray = null;
String contacts;
ListView lv;
String phoneNumber, name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
lv = (ListView) findViewById(R.id.listview);
list = new ArrayList<ProfileBean>();
getAllCallLogs(this.getContentResolver());
adapter = new SearchableAdapter(getApplication(), list);
lv.setAdapter(adapter);
lv.setItemsCanFocus(false);
lv.setOnItemClickListener(this);
lv.setTextFilterEnabled(true);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
public void getAllCallLogs(ContentResolver cr) {
Cursor phones = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
+ " ASC");
while (phones.moveToNext()) {
phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
list.add(new ProfileBean(name, phoneNumber));
}
phones.close();
}
}
If you want to get rid of duplicates, consider using a HashSet instead.
If you can't/don't want to use it, simply check before adding whether the contact is already there.
if (!myList.contains(newContact))
myList.add(newContact);
Add the following checking in the place of list.add(new ProfileBean(name, phoneNumber)); before adding into list:
int flag = 0
if(list.size() == 0){
list.add(new ProfileBean(name, phoneNumber));
}
for(int i=0;i<list.size();i++){
if(!list.get(i).getProfileName().trim().equals(name)){
flag = 1;
}else{
flag =0;
break;
}
}
if(flag == 1){
list.add(new ProfileBean(name, phoneNumber));
}
The following function can be used for removing duplicates from String ArrayList Change it according to your requirement
public ArrayList<String> listWithoutDuplicates(ArrayList<String> duplicateList) {
// Converting ArrayList to HashSet to remove duplicates
LinkedHashSet<String> listToSet = new LinkedHashSet<String>(duplicateList);
// Creating Arraylist without duplicate values
ArrayList<String> listWithoutDuplicates = new ArrayList<String>(listToSet);
return listWithoutDuplicates;
}
use below code list=removeDuplicates(list);
public List<ProfileBean> removeDuplicates(List<ProfileBean> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
#Override
public int compare(Object o1, Object o2) {
if (((ProfileBean) o1).getName().equalsIgnoreCase(((ProfileBean) o2).getName()) &&
((ProfileBean)o1).getPhoneNumber().equalsIgnoreCase(((ProfileBean)o2).getPhoneNumber())) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}
Try to get ContactsContract.Contacts.NAME_RAW_CONTACT_ID) its unique id and its used for update contacts compare your contacts with raw id is same or not as below
private void getAllContactsBackground() {
ContentResolver contentResolver = getActivity().getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor cursorInfo = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(getActivity().getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id)));
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id));
Uri pURI = Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Bitmap photo = null;
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream);
}
while (cursorInfo.moveToNext()) {
ContactsModel info = new ContactsModel();
info.contacts_id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
info.contacts_raw_id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.NAME_RAW_CONTACT_ID));
info.contacts_name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
info.contacts_mobile = cursorInfo.getString(cursorInfo.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceFirst("[^0-9]" + "91", "");
info.contacts_photo = photo;
info.contacts_photoURI = String.valueOf(pURI);
Cursor emailCur = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (emailCur.moveToNext()) {
info.contacts_email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
Log.e("email==>", "" + info.contacts_email);
}
emailCur.close();
int flag = 0;
if (arrayListAllContacts.size() == 0) {
arrayListAllContacts.add(info);
}
for (int i = 0; i < arrayListAllContacts.size(); i++) {
if (!arrayListAllContacts.get(i).getContacts_raw_id().trim().equals(info.contacts_raw_id)) {
flag = 1;
} else {
flag = 0;
break;
}
}
if (flag == 1) {
arrayListAllContacts.add(info);
}
}
cursorInfo.close();
}
}
cursor.close();
}
}
Related
I have read all the phone contacts from the device and set them to an adapter for the AutoCompleteTextView. The function that does this is:
private void storeContactsToArrayList() {
Log.d("In ", "storeContactsToArrayList() called");
List<Contact> contactList = new ArrayList<>();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if ((cur != null ? cur.getCount() : 0) > 0) {
while (cur != null && cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
// Log.i("GOT", "Name: " + name);
// Log.i("GOT", "Phone Number: " + phoneNo); //working
//To our POJO
Contact contact = new Contact();
contact.setName(name);
contact.setPhoneNumber(phoneNo);
contactList.add(contact);
}
pCur.close();
}
ArrayAdapter<Contact> contactsArrayAdapter =
new ArrayAdapter<Contact>(this, android.R.layout.simple_list_item_1, contactList);
//setting this adapter to our autocompleteTextView userInput
userInput.setAdapter(contactsArrayAdapter);
}
}
if(cur!=null){
cur.close();
}
}
However when I ran the code, I realized that the function takes quite some time to execute, which seems poor.
From what I know I should be using an inner class like AdapterTask extends Async Task to do the same thing but asynchronously without blocking my main UI thread. I tried doing so, but I could not.
Please suggest me if there are any other ways of doing the same thing wihtout using AsyncTask, or if AsyncTask is the way to go, how can I achieve the thing that the above function is doing using AsyncTask.
Thanks.
Create a separate class for background task and communicate with a listener(And interface). Below is and example Modify it as per your need.
public class FetchContacts extends AsyncTask<Void, Void, List> {
private Context activity;
private OnContactFetchListener listener;
public FetchContacts(Context context, OnContactFetchListener listener) {
activity = context;
this.listener = listener;
}
#Override
protected List doInBackground(Void... params) {
List<Contact> contactList = new ArrayList<>();
// get Contacts here
return contactList;
}
#Override
protected void onPostExecute(List list) {
super.onPostExecute(list);
if(listener!=null){
listener.onContactFetch(list);
}
}
public interface OnContactFetchListener {
void onContactFetch(List list);
}
}
Can be call as .
new FetchContacts(activity, new FetchContacts.OnContactFetchListener() {
#Override
public void onContactFetch(List contacts) {
// Here you will get the contacts
}
}).execute();
Like #ADM suggested. Create a separate class, not an inner class. FetchContacts.java
public class FetchContacts extends AsyncTask<Void, Void, List> {
private Context activity;
private OnContactFetchListener listener;
public FetchContacts(Context context, OnContactFetchListener listener) {
activity = context;
this.listener = listener;
}
#Override
protected List doInBackground(Void... voids) {
List<Contact> contactList = new ArrayList<>();
// get Contacts here
ContentResolver cr = activity.getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if ((cur != null ? cur.getCount() : 0) > 0) {
while (cur != null && cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
if (cur.getInt(cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
// Log.i("GOT", "Name: " + name);
// Log.i("GOT", "Phone Number: " + phoneNo); //working
//To our POJO
Contact contact = new Contact();
contact.setName(name);
contact.setPhoneNumber(phoneNo);
contactList.add(contact);
}
pCur.close();
}
}
}
if (cur != null) {
cur.close();
}
return contactList;
}
#Override
protected void onPostExecute(List list) {
super.onPostExecute(list);
if (listener != null) {
listener.onContactFetch(list);
}
}
public interface OnContactFetchListener {
void onContactFetch(List list);
}
}
And call the class, set the list of contacts to ArrayAdapter and the arrayadapter to the autocomplete textview as:
new FetchContacts(MainActivity.this, new FetchContacts.OnContactFetchListener() {
#Override
public void onContactFetch(List contacts) {
// Here you will get the contacts
ArrayAdapter<Contact> contactArrayAdapter = new ArrayAdapter<Contact>(MainActivity.this,
android.R.layout.simple_list_item_1, contacts);
userInput.setAdapter(contactArrayAdapter); //userInput is our AutoCompleteTextView
}
}).execute();
i am creating listview with checkbox of contact list, i have one button to select all checkboxes of contact listview. and when i set the for (int i = 0; i < 5 ; i++ ) it will select 6 checkboxes and working fine ..but when set lv.getcount(); its showing error....i think its show only getview set value.....because i also use the getview in adapter....how can i solve this problem please suggest me....??
public class Contacts extends Activity implements CompoundButton.OnCheckedChangeListener{
String name, phoneNo;
List<ContactItem> contectItem;
ArrayList<String> valuesList = new ArrayList<String>();
ListView lv;
CompoundButton b1;
String[] sender = null;
boolean flag = true;
int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
lv = (ListView) findViewById(R.id.contactList);
lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
method();
}
public void method() {
// ProgressDialog pd = new ProgressDialog(Contacts.this);
// pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//pd.setTitle("Please wait");
// pd.setMessage("Loading Contacts...");
// pd.show();
contectItem = new ArrayList<ContactItem>();
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, ContactsContract.Contacts.HAS_PHONE_NUMBER + "= 1", null, "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query
(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? ",
new String[]{id}, null);
while (pCur.moveToNext()) {
int i = 0;
phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//Toast.makeText(Contacts.this, "Name: " + name + ", Phone No: " + phoneNo, Toast.LENGTH_LONG).show();
ContactItem item = new ContactItem(phoneNo, name);
contectItem.add(item);
}
pCur.close();
contactAdpter adpter = new contactAdpter(this, R.layout.contact_list, contectItem);
lv.setAdapter(adpter);
}
}
}
// pd.dismiss();
}
public void back (View v) {
super.onBackPressed();
finish();
}
public void select_all (View v) {
if (lv.getCount() > 0) {
for (int i = 0; i <lv.getCount(); i++ ) {
View view = lv.getChildAt(i);
CheckBox chk = (CheckBox)view.findViewById(R.id.checkbox1);
chk.setChecked(true);
}
}
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int pos = lv.getPositionForView(buttonView);
if (pos != ListView.INVALID_POSITION) {
ContactItem p = contectItem.get(pos);
p.setSelected(isChecked);
if (isChecked) {
if (p.isSelected()) {
valuesList.add(p.getNumber());
}
} else {
valuesList.remove(p.getNumber());
}
}
}
Try to use "lv.getAdapter().getCount()" instade of "lv.getCount()" in select_all method for get count of listview items.
try this way
to get the child of listview
for (int i = 0; i < listView.getAdapter().getCount(); i++) {
View view = listView.getChildAt(i);
}
The following code lets me display duplicate contacts.
And when I try to delete, it deletes the duplicated number as well as the original number.
I want it to delete only the duplicated number present in the listview.
Here is my code.
public class MainActivity extends Activity {
ListView listView;
ArrayList<String> listItems = new ArrayList<String>();
Set<String> dupesRemoved = new HashSet<String>();
String[] newList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order);
Cursor cursor = null;
if(curLog != null) {
while(curLog.moveToNext()) {
String str = curLog.getString(curLog.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
//contactid = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
listItems.add(str);
}
}
dupesRemoved = findDuplicates(listItems);
String listString = dupesRemoved.toString();
listString = listString.substring(1,listString.length()-1);
newList = listString.split(", ");
//Arrays.sort(newList);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, newList);
listView.setAdapter(adapter);
}
public void deleteDupes(View view) {
String[] info = new String[2];
for (String s : newList) {
info = (getContactInfo(s));
updateContact(info[0],this,info[1]);
listView.invalidateViews();
}
}
public void updateContact(String contactId, Activity act, String type){
/* ASSERT: #contactId alreay has a work phone number */
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String selectPhone = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'" + " AND " + ContactsContract.CommonDataKinds.Phone.TYPE + "=?";
String[] phoneArgs = new String[]{contactId,type /*String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)*/};
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
.withSelection(selectPhone, phoneArgs).build());
try {
act.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
}
public static Set<String> findDuplicates(List<String> listContainingDuplicates) {
final Set<String> setToReturn = new HashSet<String>();
final Set<String> set1 = new HashSet<String>();
for (String yourInt : listContainingDuplicates) {
if (!set1.add(yourInt)) {
setToReturn.add(yourInt);
}
}
return setToReturn;
}
private String[] getContactInfo(String number)
{
String[] contactInfo = new String[2];
ContentResolver context = getContentResolver();
/// number is the phone number
Uri lookupUri = Uri.withAppendedPath(
ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(number));
String[] mPhoneNumberProjection = { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup.TYPE };
Cursor cur = context.query(lookupUri,mPhoneNumberProjection, null, null, null);
try
{
if (cur.moveToFirst())
{
contactInfo[0] = cur.getString(0);
contactInfo[1] = cur.getString(2);
return contactInfo;
}
}
finally
{
if (cur != null)
cur.close();
}
return contactInfo;
}
}
Use hashmap instead of arraylist to store items in key value pair as duplicate keys are not allowed in a map.
Java code for delete contact:
public static boolean deleteContact(Context ctx, String phone, String name) {
Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return true;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
return false;
}
Manifest permission:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
My app is taking forever to load,how can I use paging that's it would load me like 10-15 people in a page and not to take 2 minute to my app for loading??
this is my code:
thank's for the help
public class Contacts extends Util<Contact> {
public Contacts(Activity activity) {
super(activity);
}
#Override
public void init() {
list = getContactsBasic();
for (int i = 0; i < list.size(); i++) {
Contact current = list.get(i);
current.image = getContactImage(current.id);
if (current.hasPhone) {
current.phones = getContactPhones(current.id);
}
}
}
LinkedList<Contact> getContactsBasic() {
Uri contactsUri = android.provider.ContactsContract.Contacts.CONTENT_URI;
Cursor cursor = activity.getContentResolver().query(contactsUri, null, null, null, null);
LinkedList<Contact> list = new LinkedList<Contact>();
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
int id = cursor.getInt(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
String name = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));
int hasPhone = cursor.getInt(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.HAS_PHONE_NUMBER));
// add more columns here
boolean hasPhoneBoolean; //editor: or simply: boolean hasPhoneBoolean = (hasPhone == 1)
if (hasPhone == 1){
hasPhoneBoolean = true;
}
else {
hasPhoneBoolean = false;
}
Contact contact = new Contact(id, name, hasPhoneBoolean);
//Contact contact = new Contact(id, name, (hasPhone == 1) ? true : false);
list.add(contact);
}
while (cursor.moveToNext());
}
cursor.close();
}
return list;
}
LinkedList<Phone> getContactPhones(int id) {
Uri phonesUri = android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String filter = android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + String.valueOf(id);
Cursor cursor = activity.getContentResolver().query(phonesUri, null, filter, null, null);
LinkedList<Phone> list = new LinkedList<Phone>();
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String number = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));
int type = cursor.getInt(cursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.TYPE));
Phone phone = new Phone(number, type);
list.add(phone);
}
while (cursor.moveToNext());
}
Change
Cursor cursor = activity.getContentResolver().query(contactsUri, null, null, null, null);
to
Cursor cursor = activity.getContentResolver().query(contactsUri, null, null, null, "ASC LIMIT " + HOW_MANY_ROWS_YOU_NEED);
i Have two activities A and B. i used intent to jump from A to B. now in B.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
LoadData();
}
now in LoadData(), i have to load a lot of data, wo i want that when it B starts, it show a Progress bar and after loading the data, it jumps back to my activity B. how can I do this???
here is my load function
public void LoadData(Context context)
{
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
ContentResolver cr = getContentResolver();
// ContactsContract.Contacts.
// Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
// null, null, ContactsContract.Contacts.DISPLAY_NAME);
// Find the ListView resource.
Cursor cur;
cur = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
null,
selection + " AND "
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
null, sortOrder);
mainListView = (ListView) findViewById(R.id.mainListView);
// When item is tapped, toggle checked properties of CheckBox and
// Planet.
mainListView
.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View item,
int position, long id)
{
ContactsList planet = listAdapter.getItem(position);
planet.toggleChecked();
PlanetViewHolder viewHolder = (PlanetViewHolder) item
.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
// Create and populate planets.
planets = (ContactsList[]) getLastNonConfigurationInstance();
// planets = new Planet[10];
// planets.Add("asdf");
ArrayList<ContactsList> planetList = new ArrayList<ContactsList>();
String phoneNumber = null;
String phoneType = null;
count = cur.getCount();
contacts = new ContactsList[count];
if (planets == null)
{
if (cur.getCount() > 0)
{
planets = new ContactsList[cur.getCount()];
int i = 0;
//
while (cur.moveToNext())
{
String id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[]
{ id }, null);
// WHILE WE HAVE CURSOR GET THE PHONE NUMERS
while (pCur.moveToNext())
{
// Do something with phones
phoneNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
phoneType = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Pratik", name + "'s PHONE :" + phoneNumber);
Log.i("Pratik", "PHONE TYPE :" + phoneType);
}
pCur.close();
}
if (phoneNumber != null
&& !planetList.contains(new ContactsList(name,
phoneNumber)))
{
planets = new ContactsList[]
{ new ContactsList(name, phoneNumber) };
contacts[i] = planets[0];
planetList.addAll(Arrays.asList(planets));
}
phoneNumber = null;
i++;
}
}
// for (int i = 0; i < count; i++)
// {
// Log.d("New Selected Names : ", contacts[i].getName());
// }
}
// Set our custom array adapter as the ListView's adapter.
listAdapter = new PlanetArrayAdapter(this, planetList);
mainListView.setAdapter(listAdapter);
Adapter adptr;
adptr = mainListView.getAdapter();
}
Please try this
//////////////////////////////////////////////////////////////////
Edit Check It
public class LoadData extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog;
//declare other objects as per your need
#Override
protected void onPreExecute()
{
progressDialog= new ProgressDialog(YourActivity.this);
progressDialog.setTitle("Please Wait..");
progressDialog.setMessage("Loading");
progressDialog.setCancelable(false);
progressDialog.show();
//do initialization of required objects objects here
};
#Override
protected Void doInBackground(Void... params)
{
LoadData();
//do loading operation here
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
};
}
You can call this using
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
LoadData task = new LoadData();
task.execute();
}
for more help read android document
http://developer.android.com/reference/android/os/AsyncTask.html
I am agree with Kanaiya's answer because upto the API level-10 it is fine to call long running tasks on UI thread. But from API-11, any task that takes longer time (nearly more than 5 sec) to complete must be done on background thread. The reason behind this is any task that takes 5 seconds or more on UI thread then ANR(Application Not Responding) i.e. force close happens. To do that we have create some background thread or simply make use of AsyncTask.
You just need to call your LoadData() method in another thread.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
mDailog = ProgressDialog.show(ActivityA.this, "",
"Loading data....!!!", true);
mDailog.show();
new Thread() {
#Override
public void run() {
try {
LoadData();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}.start();
}
Inside your LoadData(), at the end of the method use a handler to send a message to dismiss the progress bar dialog.
Hope this will help you to avoid the complex logic using AsyncTask.
Try this.
public class BActivtiy extends Activity implements Runnable{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
mainListView = (ListView) findViewById(R.id.mainListView);
mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View item, int position, long id) {
ContactsList planet = listAdapter.getItem(position);
planet.toggleChecked();
PlanetViewHolder viewHolder = (PlanetViewHolder) item.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
pd = ProgressDialog.show(BActivity.this, "Title", "Description", true);
Thread t = new Thread(BActivity.this);
t.start();
}
public void LoadData() {
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getContentResolver();
Cursor cur;
cur = this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection + " AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1", null, sortOrder);
// Create and populate planets.
planets = (ContactsList[]) getLastNonConfigurationInstance();
// planets = new Planet[10];
// planets.Add("asdf");
ArrayList<ContactsList> planetList = new ArrayList<ContactsList>();
String phoneNumber = null;
String phoneType = null;
count = cur.getCount();
contacts = new ContactsList[count];
if (planets == null) {
if (cur.getCount() > 0) {
planets = new ContactsList[cur.getCount()];
int i = 0;
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Query phone here. Covered next
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
// WHILE WE HAVE CURSOR GET THE PHONE NUMERS
while (pCur.moveToNext()) {
// Do something with phones
phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
phoneType = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Pratik", name + "'s PHONE :" + phoneNumber);
Log.i("Pratik", "PHONE TYPE :" + phoneType);
}
pCur.close();
}
if (phoneNumber != null && !planetList.contains(new ContactsList(name, phoneNumber))) {
planets = new ContactsList[] { new ContactsList(name, phoneNumber) };
contacts[i] = planets[0];
planetList.addAll(Arrays.asList(planets));
}
phoneNumber = null;
i++;
}
}
// for (int i = 0; i < count; i++)
// {
// Log.d("New Selected Names : ", contacts[i].getName());
// }
}
}
#Override
public void run() {
LoadData();
mHandler.sendEmptyMessage(0);
}
public Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
pd.dismiss();
listAdapter = new PlanetArrayAdapter(BActivtiy.this, planetList);
mainListView.setAdapter(listAdapter);
Adapter adptr;
adptr = mainListView.getAdapter();
}
};
}