How to update a particular email Address in contacts? - android

i use the following the code to update the number:
ContentValues mobilePhoneValues = new ContentValues();
mobilePhoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, typePhone);
mobilePhoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, binding.numberEdit.getText().toString());
getContentResolver().update(ContactsContract.Data.CONTENT_URI, mobilePhoneValues,
ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{mobilePhoneNumbers.get(0)});
It works perfectly but when i try to update the email using same logic it fails to update it.
Code:
ContentValues contentValues1 = new ContentValues();
contentValues1.put(ContactsContract.CommonDataKinds.Email.TYPE, typeEmail);
contentValues1.put(ContactsContract.CommonDataKinds.Email.DATA, binding.emailEdit.getText().toString());
getContentResolver().update(ContactsContract.Data.CONTENT_URI, contentValues1,
ContactsContract.CommonDataKinds.Email.DATA + "=?", new String[]{homeEmailNumbers.get(0)});
Why is it the same logic updates the number but fails to update the email ?
Please help

There's a big problem in both examples.
You are telling the API - change any occurrence of phone (or email) "X" to "Y" across all contacts.
It depends on your use case, but I'm assuming you want to let users edit contact information.
For that use case that's not what you intend to be doing. instead, you should tell the API - take row with ID "12345" and change its value to "Y".
Adding the contact-id to the WHERE clause will also have unintended consequences when you consider a case where a certain contact has 2 duplicate phone numbers, and the user wants to edit one of them - you don't want to modify both numbers in this case.
You should first change the way you read and present the data, so every data row for every contact also holds the specific Data table row ID (Data._ID)
and then the code is:
batch update approach (preferred):
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
.withValue(CommonColumns.TYPE, newType)
.withValue(CommonColumns.DATA, newData)
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
single change approach:
ContentValues values = new ContentValues();
values.put(CommonColumns.TYPE, newType);
values.put(CommonColumns.DATA, newData);
getContentResolver().update(Data.CONTENT_URI, values,
Data._ID + "=?", new String[]{String.valueOf(dataId)});
The use of CommonColumns and Data._ID allows for the same code to work for both phones, emails, and some other common types.

Related

Can a SyncAdapter modify RawContacts added by another SyncAdapter?

If a SyncAdapter A for Account A creates a raw contact in the ContactsContract.RawContacts table, can SyncAdapter B for Account B update the RawContact added by SyncAdapter A.
Of particular interest is the sync1 or any of the sync fields in the raw contacts table?
If this is possible what are the possible issues that might arise as a result.
Can anyone show a sample of how this should be done?
There's no per-contact-permission-model on the Contacts DB, every app and every SyncAdapter with the Contacts permission can read/write to any field in any contact.
However, the syncX fields under RawContact are used for proprietary purposes by the owning SyncAdapter (e.g. to keep track on what contact requires syncing, which one is dirty, when was it last synced, the backend-contact-id value, etc.), so make sure you don't touch anything you don't know what it's for, or you might risk corrupting some contacts.
To modify the Sync1 value on RawContact with id 1234, do:
ContentResolver cr = context.getContentResolver();
ContentValues values = new ContentValues(2);
values.put(RawContacts.SYNC1, "Hello World");
cr.update(RawContacts.CONTENT_URI, values, RawContacts._ID + "=" + 1234, null);
UPDATE - batch updates
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI)
.withSelection(RawContacts._ID + "=" + 1234, null)
.withValue(RawContacts.SYNC1, "Hello")
.build());
ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI)
.withSelection(RawContacts._ID + "=" + 5678, null)
.withValue(RawContacts.SYNC1, "World")
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

Update contact name in android 4.4

I would like to modify contact's name in an Android device (GT N5110) with Android 4.4. I have tried to do that by this approach:
ContentValues contentValues = new ContentValues();
String selection = ContactsContract.Contacts._ID + " = ? " ;
String[] selectionArgs = new String[] { Integer.toString(id) };
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, lastName);
contentValues.put(ContactsContract.Contacts.STARRED, 2); // *
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastName);
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstName);
return this.context.getContentResolver().update(ContactsContract.Contacts.CONTENT_URI,
contentValues, selection, selectionArgs);
The line marked with * was the only one which modified the contact database. I also tried by applyBatch and added the MIMETYPE selection (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE). The MIMETYPE approach throws some Exception with these message:
android.database.sqlite.SQLiteException: no such column: mimetype (code 1): , while compiling: SELECT _id FROM view_contacts_restricted WHERE _id = ? AND mimetype=?
I researched and tried suggestions present in update contacts display_name and Modifying contact information.
Can someone help me?
The following website explains it to you. It is a full tutorial by android itself. I highly recommend you use this website to first check if there is an answer to your query first before coming here.
http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#EXTRA_FORCE_CREATE
What this website explains to you is
Send data to the contact you require to edit and it automatically opens the contact edit screen with the details which you passed to it.
If you want to know what all extras you can send to it. Visit the following link.
https://developer.android.com/reference/android/provider/ContactsContract.Intents.Insert.html
I am not sure if this is correct but it may be because of some security policy or so that you can't skip ui confirmation. But again I am not familiar with this so I may be wrong. I have not tested if this works or anything but I think it might help. Especially the second one:
http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#EXTRA_FORCE_CREATE
And
http://www.techjini.com/blog/2011/10/31/insert-and-modify-contact-in-android/

Android set contact to favorite programmatically

Can any one told me if I have a list of contact and read them in my application and I want to set contact to favorite from my application directly, so that when I open my phone contact again I will be able to find contact in the favorite list of android phone.
Please help
you must add permission to your application to be able to write to the contact content provider.
android.permission.WRITE_CONTACTS
android.permission.READ_CONTACTS
After that you need to update the value for the STARRED field.
ContentValues v = new ContentValues();
v.put(ContactsContract.Contacts.STARRED,1);
getContentResolver().update(ContactsContract.Contacts.CONTENT_URI, v, ContactsContract.Contacts.Data.DATA1+"=?", new String[]{putThePhoneNumberHere+""});
You need to update value STARRED in contacts database from 0 to 1.
Something like:
values.put(Contacts.STARRED, 1);
getContentResolver().update(Contacts.CONTENT_URI, values, Contacts.DISPLAY_NAME + "= ?", strNamevalue);
This is a sql query:
UPDATE %Contacts.CONTENT_URI% SET STARRED = 1 WHERE %Contacts.DISPLAY_NAME% = %strNamevalue%
Values in %% should be replaced by valid table name and where clause params
Hope it helps

Deleting a specific RawContact content directory entry

I'm new to android dev, so I may get the whole concept totally wrong. I want to delete a specific entry from RawContact directory entry. Here is code that I have:
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
Uri entityUri = Uri.withAppendedPath(rawContactUri, Entity.CONTENT_DIRECTORY);
Cursor c = getContentResolver().query(entityUri,
new String[]{RawContacts._ID, Entity.DATA_ID, Entity.MIMETYPE,CommonDataKinds.GroupMembership.GROUP_SOURCE_ID},
null, null, null);
using cursor c I get appropriate Entity.DATA_ID. After that I try to delete an entry:
getContentResolver().delete(entityUri,Entity.DATA_ID+"=?",
new String[]{id});
and get an error:
java.lang.UnsupportedOperationException: URI:
content://com.android.contacts/raw_contacts/2709/entity
What am I doing wrong?
UPD 1
I am trying to remove group membership entry.
Please give a more complete explanation of what you're trying to do. You say that you want to "delete a specific entry from RawContact directory entry.", which is confusing? Do you want to
a) delete a raw contact?
b) delete a set of raw contacts?
c) delete all of the data rows for a single raw contact?
d) delete all of the data rows for a set of raw contacts?
or do you want to do something with group membership?
In any event, I think you've constructed the URI backwards. Try appending Entity.CONTENT_DIRECTORY before the rawContactId. I know that the documentation doesn't say this, but the documentation is not well-written.
A better alternative would be to use the ContactsContract.RawContactEntity table.
Looks like I was using the wrong URI. Also I switched to a "new" way of modifying the table:
ArrayList<ContentProviderOperation> ops =
new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
.withSelection(Data._ID + "=?", new String[]{i})
.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

Is it safe to make the assumption that generic data column is not used by any other application for storing it own contact data

I am using the generic columns DATA1 to Data15 to store some data. My question is whether it is safe to assume that these columns are not being used by other android applications to store their own data. IF not how would I make sure that a particular column is not being used by any other application?
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withValue(Data.DATA10,"Data")
Retrive data:
ContentResolver cr=context.getContentResolver();
Cursor emailCur = cr.query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data._ID + " = ?",
new String[]{str_id}, null);
while (emailCur.moveToNext())
{
String name=emailCur.getString(
emailCur.getColumnIndex(Data.DATA10));
}
It will be safe, if you use your own MIME type value for the MIMETYPE column. When querying the data table, a MIME is specified to query for specific results (Phone numbers, names, addresses and so on), so if you use a value special for your application, other applications will probably not use it/change it.
Read more about the data table here.
EDIT: Append this call to the ContentProviderOperation creation chain:
.withValue(Data.MIMETYPE, "yourCustomMimeType")

Categories

Resources