Related
In my android code
I want to fetch contact's name,email and phone number as as json and then want to display.
Here is my code:
public class MainActivity extends Activity {
public TextView outputText;
String[] phoneNumber;
String[] email;
String name;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
outputText = (TextView) findViewById(R.id.textView1);
try {
//fetchContacts();
outputText.setText(fetchContacts());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String fetchContacts() throws JSONException {
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
Uri EmailCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String DATA = ContactsContract.CommonDataKinds.Email.DATA;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
null);
List<Contact> contacts = new ArrayList<Contact>();
Gson gson = new Gson();
// Loop for every contact in the phone
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor
.getString(cursor.getColumnIndex(_ID));
name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
int p = 0;
// Query and loop for every phone number of the contact
Cursor phoneCursor = contentResolver.query(
PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
new String[] { contact_id }, null);
while (phoneCursor.moveToNext()) {
phoneNumber[p] = phoneCursor.getString(phoneCursor
.getColumnIndex(NUMBER));
p++;
}
phoneCursor.close();
int q = 0;
// Query and loop for every email of the contact
Cursor emailCursor = contentResolver.query(
EmailCONTENT_URI, null, EmailCONTACT_ID + " = ?",
new String[] { contact_id }, null);
while (emailCursor.moveToNext()) {
email[q] = emailCursor.getString(emailCursor
.getColumnIndex(DATA));
q++;
}
emailCursor.close();
contacts.add(new Contact(name, phoneNumber, email));
}
}
}
return gson.toJson(contacts);
}
}
But I am getting nullpointer exception error :
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.contactdemo/com.example.contactdemo.MainActivity}: java.lang.NullPointerException
error found in below line of code:
phoneNumber[p] = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
Here I am storing phonenumber and email as array.Is there array initialization problem ?? any idea guys?
You can use these approach to finds the contact from contact list
class FetchDeviceContact extends AsyncTask<Void, Integer, String>
{
protected void onPreExecute (){
Constant.showProgressDialog(AddDeviceContactScreeen.this);
}
protected String doInBackground(Void...arg0) {
arrayList.clear();
ContentResolver cr = AddDeviceContactScreeen.this.getContentResolver();
Cursor cur = AddDeviceContactScreeen.this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Data._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
String photoUri = cur.getString(cur.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
Bitmap my_btmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_arrow_up_blue);
String email = null;
String phoneNo = null;
Cursor phonecur = AddDeviceContactScreeen.this.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{id}, null);
if (photoUri != null) {
Uri my_contact_Uri = Uri.parse(photoUri);
try {
my_btmp = MediaStore.Images.Media.getBitmap(AddDeviceContactScreeen.this.getContentResolver(), my_contact_Uri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (phonecur.getCount() > 0) {
while (phonecur.moveToNext()) {
phoneNo = phonecur.getString(phonecur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
Cursor emailCur = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null);
while (emailCur.moveToNext()) {
// to get the contact names
// = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)
email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
if (email != null) {
System.out.println("Email============== :" + email);
}
}
emailCur.close();
ContactBean bean = new ContactBean();
bean.setName(name);
bean.setEmail(email);
bean.setImage(my_btmp);
bean.setPhone_number(phoneNo);
if (phoneNo == null || email == null) {
} else {
arrayList.add(bean);
}
}
return "";
}
protected void onProgressUpdate(Integer...a){
}
protected void onPostExecute(String result) {
Constant.cancelDialog();
}
}
new FetchDeviceContact().execute();
Create the getter and setter class for it:-
public class ContactBean {
String name;
String email;
Bitmap image;
String phone_number;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public String getPhone_number() {
return phone_number;
}
public void setPhone_number(String phone_number) {
this.phone_number = phone_number;
}
}
I think you should fix :
if (phoneCursor.movetoFirst()){
while (!phoneCursor.isAfterLast()) {
phoneNumber[p] = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
p++;
phoneCursor.movetoNext();
}
}
Here:
phoneNumber[p] = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
NullPointerException caused because phoneNumber is null and not initialized.
Use Cursor. getCount() to initialize it as:
phoneNumber = new String[phoneCursor.getCount()];
phoneCursor.moveToFirst();
while (phoneCursor.moveToNext()) {
//..your code here..
}
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" />
I’m trying to get phone number from contacts by providing the phone number. what I've done so far:
public static String getPhone(Context context, String displayName) {
ContentResolver cr = context.getContentResolver();
Uri uri = CommonDataKinds.Phone.CONTENT_URI;
String selection = CommonDataKinds.Phone.DISPLAY_NAME+" LIKE '%" + displayName + "&'";
Cursor cursor = cr.query(uri, new String[]{CommonDataKinds.Phone._ID,CommonDataKinds.Phone.DISPLAY_NAME,CommonDataKinds.Phone.NUMBER}, selection, null, null);
if (cursor == null) {
return null;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER));
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
//Log.d("Contact",contactName.toString());
return contactName;
}
Try this code out. You will need to set the permission in the manifest "android.permission.READ_CONTACTS" on true.
public String getPhoneNumber(String name, Context context) {
String ret = null;
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" like'%" + name +"%'";
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor c = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, null, null);
if (c.moveToFirst()) {
ret = c.getString(0);
}
c.close();
if(ret==null)
ret = "Unsaved";
return ret;
}
UPDATE:
This code snippet will allow you to read all messages from a particular contact:
StringBuilder smsBuilder = new StringBuilder();
final String SMS_URI_INBOX = "content://sms/inbox";
final String SMS_URI_ALL = "content://sms/";
try {
Uri uri = Uri.parse(SMS_URI_INBOX);
String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" };
Cursor cur = getContentResolver().query(uri, projection, "address='123456789'", null, "date desc");
if (cur.moveToFirst()) {
int index_Address = cur.getColumnIndex("address");
int index_Person = cur.getColumnIndex("person");
int index_Body = cur.getColumnIndex("body");
int index_Date = cur.getColumnIndex("date");
int index_Type = cur.getColumnIndex("type");
do {
String strAddress = cur.getString(index_Address);
int intPerson = cur.getInt(index_Person);
String strbody = cur.getString(index_Body);
long longDate = cur.getLong(index_Date);
int int_Type = cur.getInt(index_Type);
smsBuilder.append("[ ");
smsBuilder.append(strAddress + ", ");
smsBuilder.append(intPerson + ", ");
smsBuilder.append(strbody + ", ");
smsBuilder.append(longDate + ", ");
smsBuilder.append(int_Type);
smsBuilder.append(" ]\n\n");
} while (cur.moveToNext());
if (!cur.isClosed()) {
cur.close();
cur = null;
}
} else {
smsBuilder.append("no result!");
} // end if
}
} catch (SQLiteException ex) {
Log.d("SQLiteException", ex.getMessage());
}
I had written a code to fetch contact name, phone number and image from Contacts and to display it on a listview in android. It's working fine but taking more time to load. I had tried to use multi-threading in some parts of the code. But the loading time is not decreased.
Here is the onCreate() method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvDetail = (ListView) findViewById(R.id.listView1);
fetchcontacts();
lvDetail.setAdapter(new MyBaseAdapter(context, myList));
}
Here is the code for fetch contacts:
private void fetchcontacts() {
// TODO Auto-generated method stub
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
int count = cursor.getCount();
if (count > 0) {
Toast.makeText(context, "count >0", Toast.LENGTH_SHORT).show();
while (cursor.moveToNext()) {
String columnId = ContactsContract.Contacts._ID;
int cursorIndex = cursor.getColumnIndex(columnId);
String id = cursor.getString(cursorIndex);
name = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Toast.makeText(context, "Toast 1", Toast.LENGTH_SHORT).show();
int numCount = Integer.parseInt(cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
if (numCount > 0) {
Toast.makeText(context, "Toast 2", Toast.LENGTH_SHORT).show();
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
CommonDataKinds.Phone.CONTACT_ID+" = ?", new String[] { id
}, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
while (phoneCursor.moveToNext()) {
Toast.makeText(context, "Toast 3", Toast.LENGTH_SHORT).show();
phoneNo = phoneCursor.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.
Phone.NUMBER));
String image_uri = phoneCursor
.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (image_uri != null) {
Toast.makeText(context, "Toast 4", Toast.LENGTH_SHORT).show();
System.out.println(Uri.parse(image_uri));
try {
bitmap = MediaStore.Images.Media
.getBitmap(this.getContentResolver(),
Uri.parse(image_uri));
// sb.append("\n Image in Bitmap:" + bitmap);
// System.out.println(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
getDataInList(name,phoneNo,bitmap);
name=null;
phoneNo=null;
Drawable myDrawable = getResources().getDrawable(R.drawable.star1);
bitmap = ((BitmapDrawable) myDrawable).getBitmap();
}
phoneCursor.close();
}
}
}
Here the setAdapter() function of the listview is working after fetching all the contacts to an ArrayList. do anyone have idea about how to display the contacts during fetching contacts? any sample code?
1.Read the Columns from the Cursor which you required only ,According to your requirement you just need _ID,HAS_PHONE_NUMBER,DISPLAY_NAME ,so change the Cursor reading
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.DISPLAY_NAME }, null, null,
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
2.Dont do the time taking process in the UI thread..Use AsyncTask instead
Note : This two steps will resolve to some extent..but not completely
I made it by reduce repeated query wich is expensive. Best of my solution is that method found all mobile phones and email for each contact and insert to list for every contact values. It is fast as storm now :)
//contact entity
public class MobileContact {
public String name;
public String contact;
public Type type;
public MobileContact(String contact, Type type) {
name = "";
this.contact = contact;
this.type = type;
}
public MobileContact(String name, String contact, Type type) {
this.name = name;
this.contact = contact;
this.type = type;
}
public enum Type {
EMAIL, PHONE
}
#Override
public String toString() {
return "MobileContact{" +
"name='" + name + '\'' +
", contact='" + contact + '\'' +
", type=" + type +
'}';
}
}
// method for collect contacts
public List<MobileContact> getAllContacts() {
log.debug("get all contacts");
List<MobileContact> mobileContacts = new ArrayList<>();
ContentResolver contentResolver = context.getContentResolver();
// add all mobiles contact
Cursor phonesCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.CONTACT_ID}, null, null, null);
while (phonesCursor != null && phonesCursor.moveToNext()) {
String contactId = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "");
mobileContacts.add(new MobileContact(contactId, phoneNumber, MobileContact.Type.PHONE));
}
if (phonesCursor != null) {
phonesCursor.close();
}
// add all email contact
Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Email.DATA, ContactsContract.CommonDataKinds.Email.CONTACT_ID}, null, null, null);
while (emailCursor != null && emailCursor.moveToNext()) {
String contactId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID));
String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
mobileContacts.add(new MobileContact(contactId, email, MobileContact.Type.EMAIL));
}
if (emailCursor != null) {
emailCursor.close();
}
// get contact name map
Map<String, String> contactMap = new HashMap<>();
Cursor contactsCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER}, null, null, ContactsContract.Contacts.DISPLAY_NAME);
while (contactsCursor != null && contactsCursor.moveToNext()) {
String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
String contactName = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactMap.put(contactId, contactName);
}
if (phonesCursor != null) {
phonesCursor.close();
}
// replace contactId to display name
for (MobileContact mobileContact : mobileContacts) {
String displayName = contactMap.get(mobileContact.name);
mobileContact.name = displayName != null ? displayName : "";
}
// sort list by name
Collections.sort(mobileContacts, new Comparator<MobileContact>() {
#Override
public int compare(MobileContact c1, MobileContact c2) {
return c1.name.compareTo(c2.name);
}
});
return mobileContacts;
}
The contacts in larse size use in backround task.
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number[i]));
ContentResolver contentResolver = getContentResolver();
Cursor search = contentResolver.query(uri, new String[]{ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
try {
if (search != null && search.getCount() > 0) {
search.moveToNext();
name = search.getString(search.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
id = search.getString(search.getColumnIndex(ContactsContract.Data._ID));
System.out.println("name" + name + "id" + id);
/* tv_name.setText(name);
tv_id.setText(id);
tv_phone.setText(number);*/
}
} finally {
if (search != null) {
search.close();
}
}
Fastest way for me soo far .
ContentResolver cr = mContext.getContentResolver(); Cursor cursor= mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); if (cursor!= null) { final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); String displayName, number = null, idValue; while (cursor.moveToNext()) {
displayName = cursor.getString(displayNameIndex);
idValue= cursor.getString(idIndex);
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null);
phones.moveToFirst();
try {
number = phones.getString(phones.getColumnIndex("data1"));
}
catch (CursorIndexOutOfBoundsException e)
{`
}
phones.close();
userList.add(new ContactModel(displayName , number , null , }
EDIT:A list of what I consider important contact details:
1.NAME
2.PHONE NUMBER
3.EMAIL ADDRESS
4.WEBSITE
5.PHYSICAL ADDRESS
I would prefer to do this using a pre-fetched contactId...using only one cursor to get all of the data specified.I,preferably would like to find the right query to do this:
I would like to get all of the important details of a Contact at once,I am using the following code to do this:
public void getAllDataByContactId(int contactId)
{
Log.d(TAG, "Seriously scared it might not work");
String phoneNo="Phone disconnected";
String email="Email could not be delivered";
String website="Website 404";
String address="Number 13,Dark Street,Area 51,Bermuda Trianlge";
String name="Clint Eastwood";
int hasPhoneNumber;
String selection=ContactsContract.Data.CONTACT_ID+"=?";
String[] selectionArgs={String.valueOf(contactId)};
Cursor c=context.getContentResolver().query(ContactsContract.Data.CONTENT_URI, null,selection, selectionArgs,ContactsContract.Data.TIMES_CONTACTED);
if(c!=null && c.getCount()>0)
{
while(c.moveToNext())
{
phoneNo=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d(TAG, "Phone number: "+phoneNo);
email=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
Log.d(TAG, "Email: "+email);
website=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL));
Log.d(TAG, "Website :"+website);
address=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
name=c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
Log.d(TAG, "Name :"+name);
}
}
}
However,although this does not throw an error it shows many rows consisting of an empty string interspresed with the actual values.How do I write a query that cuts out the noise?
I have tried this and this gets me all the values:
String selection=ContactsContract.Data.CONTACT_ID+"=? AND "+ContactsContract.Data.MIMETYPE+"=? OR "+ContactsContract.Data.MIMETYPE+"=? OR "+ContactsContract.Data.MIMETYPE+"=? OR "+ContactsContract.Data.MIMETYPE+"=? OR "+ContactsContract.Data.MIMETYPE+"=?";
String[] selectionArgs={String.valueOf(contactId),ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE,ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE};
Too late to answer, but maybe it can help someone in the future.
My solution for this question with only one while cycle and query:
private void fetchContacts(ContentResolver contentResolver) {
if (contentResolver == null) return;
Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
null, null, null, null);
if (cursor == null || cursor.getCount() <= 0) {
return;
}
String prevId = "";
String contactId = "";
PersonContact personContact = null;
while (cursor.moveToNext()) {
String company = "";
String columnName = cursor.getString(cursor.getColumnIndex("mimetype"));
if (columnName.equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)) {
company = cursor.getString(cursor.getColumnIndex("data1"));
}
String email = "";
if (columnName.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
email = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
String phone = "";
if (columnName.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
phone = cursor.getString(cursor.getColumnIndex("data1"));
}
String first = "";
String last = "";
if (columnName.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
first = cursor.getString(cursor.getColumnIndex("data2"));
last = cursor.getString(cursor.getColumnIndex("data3"));
}
if (!prevId.equals(contactId)) {
if (!TextUtils.isEmpty(prevId)) {
addFilteredList(personContact);
allContacts.put(prevId, personContact);
}
prevId = contactId;
personContact = new PersonContact();
} else {
if (personContact != null) {
personContact.id = prevId;
if (TextUtils.isEmpty(personContact.company)) personContact.company = company;
if (TextUtils.isEmpty(personContact.firstName)) personContact.firstName = first;
if (TextUtils.isEmpty(personContact.lastName)) personContact.lastName = last;
if (!TextUtils.isEmpty(email) && personContact.emails.size() == 0) {
personContact.emails.add(email);
}
if (!TextUtils.isEmpty(phone) && personContact.phoneNumbers.size() == 0) {
personContact.phoneNumbers.add(phone);
}
}
}
contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
}
cursor.close();
}
As you can see, I used the prevId field, because cursor.moveToNext performs several times for one contact (once for first and last names, one for phone, etc.). After each iteration, I check the previous contact identifier with the current identifier and, if it is false, I update the fields in the personContact model.
May not be the best solution. But this is how I achieved it.
ArrayList<String> fnameList = new ArrayList<>();
ArrayList<String> lnameList = new ArrayList<>();
ArrayList<String> mnumList = new ArrayList<>();
ArrayList<String> hnumList = new ArrayList<>();
ArrayList<String> wnumList = new ArrayList<>();
ArrayList<String> mailList = new ArrayList<>();
final DynamoDBMapper dynamoDBMapper = AWSMobileClient.defaultMobileClient().getDynamoDBMapper();
final ContactsDO firstItem = new ContactsDO(); // Initialize the Notes Object
firstItem.setUserId(AWSMobileClient.defaultMobileClient().getIdentityManager().getCachedUserID());
String email = null;
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri EmailCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
String DATA = ContactsContract.CommonDataKinds.Email.DATA;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
// Loop for every contact in the phone
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
// Query and loop for every phone number of the contact
Cursor pCur = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[]{contact_id}, ContactsContract.CommonDataKinds.Phone.NUMBER);
int flag = 0;
assert pCur != null;
while (pCur.moveToNext()) {
String mobileNum = pCur.getString(pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
if (flag == 0) {
if(mobileNum!=null){
mnumList.add(mobileNum);}
} else if (flag == 1) {
if(mobileNum!=null){
hnumList.add(mobileNum);}
} else if (flag == 2) {
if(mobileNum!=null){
wnumList.add(mobileNum);}
}
flag++;
}
if(flag==1){
hnumList.add("");
wnumList.add("");
Log.e("Set","Both added");
}
if(flag==2){
wnumList.add("");
Log.e("Set","W added");
}
pCur.close();
}
}
}
cursor.close();
String MIME = ContactsContract.Data.MIMETYPE + "=?";
String[] params = new String[]{ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE};
final Cursor nameCur = contentResolver.query(
ContactsContract.Data.CONTENT_URI,
null,
MIME,
params,
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
assert nameCur != null;
int i = 0;
while (nameCur.moveToNext()){
String fname = "";
String lname = "";
fname = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
lname = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
Log.e("In While","All the time");
if(fname!=null){
fnameList.add(fname);
Log.e("Put","Value Fname "+fname);}
if(lname!=null) {
lnameList.add(lname);
Log.e("Put","Value Lname "+lname);
}
if(fname==null){
fnameList.add(" ");
}
if(lname==null){
lnameList.add(" ");
}
i++;
}
nameCur.close();
Cursor cursorB = contentResolver.query(CONTENT_URI, null, null, null, null);
// Loop for every contact in the phone
if (cursorB.getCount() > 0) {
while (cursorB.moveToNext()) {
// Query and loop for every email of the contact
String[] paramEmail = new String[]{ContactsContract.CommonDataKinds.Email.CONTENT_TYPE};
Cursor emailCursor = contentResolver.query(EmailCONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", paramEmail, ContactsContract.CommonDataKinds.Email.DISPLAY_NAME);
int j=0;
while (emailCursor.moveToNext()) {
email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
mailList.add(email);
Log.e("Email",email);
j++;
}
if(j==0){
mailList.add("");
Log.e("Email","Dummy Added");
}
emailCursor.close();
output.append("\n");
}
}cursorB.close();
Cursor cursorD = contentResolver.query(CONTENT_URI, null, null, null, null);
// Loop for every contact in the phone
if (cursorD.getCount() > 0) {
while (cursorD.moveToNext()) {
String contact_id = cursorD.getString(cursorD.getColumnIndex(_ID));
//for url
String newNoteUrl = "";
String whereName3 = ContactsContract.Data.MIMETYPE + " = ?";
String[] whereNameParams3 = new String[]{ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE};
ContentResolver contentResolverUrl = this.getContentResolver();
try {
Cursor cursorUrl = contentResolverUrl.query(ContactsContract.Data.CONTENT_URI, null, whereName3, new String[]{contact_id}, ContactsContract.CommonDataKinds.Website.URL);
while (cursorUrl.moveToNext()) {
newNoteUrl = cursorUrl.getString(cursorUrl.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL));
Log.e("URL",newNoteUrl);
}
Log.e("URL","Not Getting");
output.append("\nurl " + newNoteUrl);
firstItem.setUrl(newNoteUrl);
cursorUrl.close();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}cursorD.close();
Log.e("#######","##########################");
for(int m=0;m<fnameList.size();m++){
Log.e("Contact Val ",fnameList.get(m)+" , "+lnameList.get(m)+" , "+mnumList.get(m)+" , "+hnumList.get(m)+" , "+wnumList.get(m)+" , "+mailList.get(m));
ContactsDO item = new ContactsDO();
item.setUserId(AWSMobileClient.defaultMobileClient().getIdentityManager().getCachedUserID());
item.setFirstName(fnameList.get(m));
item.setLastName(lnameList.get(m));
item.setMobileNumber(mnumList.get(m));
item.setHomeNumber(hnumList.get(m));
item.setWorkNumber(wnumList.get(m));
item.setEmail(mailList.get(m));
try {
//saving to the database
dynamoDBMapper.save(item);
} catch (final AmazonClientException ex) {
Log.e(TAG, "Failed saving item : " + ex.getMessage(), ex);
}
}