How to update Android contact company? - android

I recently created a Sync adapter for my app, It will sync contacts I am getting via a web request with the contacts in the phone. I have no problem adding the contact, however I cannot get the contact information to correctly update when contact information has changed. For example the Company Name field on the contact. Here is some example queries I have tried that did not work or only partially worked(ie - some contacts updated but not correctly):
ContentValues values = new ContentValues();
values.put(ContactsContract.CommonDataKinds.Organization.COMPANY, "New Company");
context.getContentResolver().update(Uri.parse("content://com.android.contacts/data/"), values, BaseColumns._ID + "=?", new String[] { String.valueOf(id) } );
I have also tried doing this in batch as suggested by the android documentation:
builder = ContentProviderOperation
.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(BaseColumns._ID + " =?", new String[]{String.valueOf(id)});
builder.withValue(
ContactsContract.CommonDataKinds.Organization.COMPANY,
"New Company Name!");
operationList.add(builder.build());
I have read the ContactContracts Documentation and originally was following this tutorial. I also checked into the AuthenticatorActivity example in the api's to no avail. Any help is greatly appreciated.

After spending an exhausting amount of time trying to figure out the correct query, I believe I have found the answer. It looks like i needed to change the BaseColumns._ID to ContactsContract.Data.CONTACT_ID and for each update I made, I also had to supply the mime-type also I did not see this anywhere in the android documentation. Much help was found on this write-up: Working With Android Contacts
String orgWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] orgWhereParams = new String[]{String.valueOf(id),
ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE};
operationList
.add(ContentProviderOperation
.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(orgWhere, orgWhereParams)
.withValue(
ContactsContract.CommonDataKinds.Organization.DATA,
guCon.getCompany()).build());

Related

Unable to delete specific number in a Contact in Android

I'm working on an application in which I should be able to access all the contacts, able to update or delete the numbers in any contact.
I want to delete few numbers in a contact. I'm using batchOperations to perform delete operation.
phone = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ? AND " +
ContactsContract.CommonDataKinds.Phone._ID + " = ?";
String[] phoneArgs = new String[]{Integer.toString(rawContactId), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, String.valueOf(id)};
batchOperations.add(ContentProviderOperation.newDelete(Data.CONTENT_URI).withSelection(phone, phoneArgs).build());
this.mContext.getContentResolver().applyBatch("com.android.contacts", batchOperations);
batchOperations.clear();
I'm using this part of code to delete a specific number from the Contact. Using debugger, for a sample delete operation, I found the values as:
raw_contact_id = 4093
id = 21579
These values correspond to specific number("+814444444444") in a group of numbers in a sample contact.(Please refer image below)
But still the number is not getting deleted. I've been trying to figure it out for the last couple of hours but couldn't solve it. Please help.
Instead of supplying selection + selectionArgs, you can build a uri of the specific item you want to delete, like so:
Uri phoneUri = ContentUris.withAppendedId(Data.CONTENT_URI, phoneId);
batchOperations.add(ContentProviderOperation.newDelete(phoneUri).build());
A couple of other notes:
Always check the return value of applyBatch, if it's false, there's some issue with your code / permissions.
Use the constant ContactsContract.AUTHORITY instead of the hard-coded string "com.android.contacts".
Another reason for the observed behavior is that the phone "+814444444444" is stored on multiple RawContacts aggregated into a single contact.
In which case even when you properly delete the row from RawContact A, the contact profile would still get the number from RawContact B.
This is especially true for phone numbers when certain apps such as Whatsapp are installed which tend to copy over contacts' phone numbers to a separate RawContact under their own account.
If that's the issue you'll need to delete the phone number from ALL the contact's RawContacts holding that phone.
EDIT
Here's how to dump all phone numbers that belong to a specific contact, along with the raw-contact that holds them:
String selection = Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?";
String[] selectionArgs = new String[] { contactId.toString(), Phone.CONTENT_ITEM_TYPE };
String[] projection = new String[] { Data.CONTACT_ID, Data.RAW_CONTACT_ID, Data.DATA1 };
Cursor cur = getContentResolver().query(Data.CONTENT_URI, projection, selection, selectionArgs, projection);
DatabaseUtils.dumpCursor(cur);
Also, note that a rawContactId is not an integer, it's a long.

Getting email and phone from contacts Android

I'm attempting to retrieve both email and phone via a single cursor described below. I'm using the Email.CONTENT_URI, hence I don't retrieve the phone number, so my phoneColumn is returning email. I tried using Phone.CONTENT_URI but it only returns a smaller subset of contacts (possibly because it only fetches ones that have phone numbers). Is there a way to get both email and phone with a specific Uri or how can I do it with two cursors?
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
projection, null, null, order);
int idColumn = cursor.getColumnIndex(ContactsContract.Data._ID);
int nameColumn = cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
int emailColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
int phoneColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA);
where projection is:
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Phone.DATA, }
Please have a look here. You should find all the necessary examples for such kind of querying.
For an example, you can fetch all information of a contactId in this way:
Cursor data = context.getContentResolver().query(
Data.CONTENT_URI, new String[] { Data._ID,Data.MIMETYPE,
Email.ADDRESS, Photo.PHOTO},Data.CONTACT_ID
+ "=?" + " AND " + "(" + Data.MIMETYPE + "='"
+ Photo.CONTENT_ITEM_TYPE + "' OR " + Data.MIMETYPE
+ "='" + Email.CONTENT_ITEM_TYPE +"')",
new String[] {String.valueOf(contactId)}, null);
You can fetch info for all contacts in this way and then probably sort it according to your criteria. You can build queries like this based on your need.
I have created this library to solve all your queries. It will only save contacts with at least one email or phone number. Also it will remove duplicates from emails and phone numbers from same contacts (created by 3rd party apps like whatsapp).
Please have a look at it.
Link : https://github.com/raghavsatyadev/ContactFetcher/

Reading birthdays from device leads to duplicated entries in cursor

I am trying to read the birthdays of all my contacts. My code works prefectly fine with most of the contacts, but I get a little problem with a few contacts as they appear twice in my cursor. Regarding to my researches this does always happen when a contact for example is both stored in the device manually and imported from skype to the contacts. I haven't tested it with other imported contacts (like facebook etc.), but I assume I will run into the same problem there. Here is my code so far:
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.START_DATE };
String selection = ContactsContract.Data.MIMETYPE + "= ? AND " +
ContactsContract.CommonDataKinds.Event.TYPE + "= ? AND "+
ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?";
String[] selectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE,
Integer.toString(ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY),
"1"};
ContentResolver cr = getContentResolver();
Cursor c = cr.query(ContactsContract.Data.CONTENT_URI, projection, selection, selectionArgs, null);
while (c.moveToNext()) {
String id = c.getString(0);
String name = c.getString(1);
String bday = c.getString(2);
Log.d(TAG, "id: " + id + ", name: " + name + ", bday: " + bday);
}
When I run this code my contact imported from Skype will show up twice in the logcat:
id: 251, name: Homer Simpson, bday: 1956-05-12
id: 502, name: Homer Simpson, bday: 12.05.1956
As you can see the entry has different IDs so I cannot solve my problem via the _ID attribute (Someone suggested that here: Android Applicaiton - How to get birthday of a contact). I also see Homer Simpson only once in my contact list. The perfect solution would be to only get the birthday from skype, when there is no birthday for that contact stored in my device manually. I started looking around for a solution and found a lot suggestions using the LOOKUP_KEY, but I struggled in implementing this and am not sure if that's the correct way to solve my problem.
Does anyone have any ideas how to fix this? Every approach will be appreciated! Thank you !

Android Contact Picking Uri

I have a string content//com.android.contacts/contacts/contacts/2 ie aft the user has selected a particular number.
From this string, how do i get the phone number of this particular contact?
I am new to android environment, so my question might seem a bit primitive.
Cursor c = (Cursor)mAdapter.getItem(a.keyAt(i));
Long id = c.getLong(c.getColumnIndex(ContactsContract.Contacts._ID));
contacts.add(ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id));
chosenContacts = sb.toString();
chosenContacts is my string and that contains content//com.android.contacts/contacts/contacts/2
You need a second request. You can use the id of your snippet for it:
Cursor phoneNoCursor = contentResolver.query(
Data.CONTENT_URI,
new String[] {Phone.NUMBER, Phone.TYPE, Phone.LABEL},
Data.MIMETYPE + " = ? AND " + Data.CONTACT_ID + " = ? ",
new String[] {String.valueOf(Phone.CONTENT_ITEM_TYPE, id)},
null);
For the list of possible types see the description of the Phone class. But maybe the number itself and its label are enough anyway.

Find contacts with given display name

Learning Android I'm trying to find contacts using DISPLAY_NAME selector. I need to find all contacts with given name. Everything goes great using standard query, but falls when I use ContentProviderOperation. I do not understand some of features. When debugging i see exception: Empty values. But, which values I must insert there? Thanks.
op.add(ContentProviderOperation.newAssertQuery(ContactsContract.Contacts.CONTENT_URI)
.withSelection(ContactsContract.Contacts.DISPLAY_NAME + " = '" + name + "'", new String[] {ContactsContract.Contacts._ID})
.build());
try {
result = getContentResolver().applyBatch(ContactsContract.AUTHORITY, op);
} catch (Exception e) {
}
the problem is with your second line of code which should read:
.withSelection(
ContactsContract.Contacts.DISPLAY_NAME + " = ?",
new String[] {name}
)
To explain, the withSelection method takes two parameters, the selection string and an array selectionArgs, these are substituted into the selection string during query compilation. So in this example the ? is subtituted for the value of name. Text qualifiers (single quotes) are automatically embedded at the same time so no additional effort is required

Categories

Resources