Why am I unable to update the email address in android? - android

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.clear();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(Data._ID + "=?", new String[]{String.valueOf(id)})
.withValue(Email.DATA, "somebody1#android.com")
.build());
try
{
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
The logs don't show me anything. But the email is not updated. Does anyone know why?
The ops converted to string is as follows:
[mType: 2, mUri: content://com.android.contacts/data, mSelection: _id=?, mExpectedCount: null, mYieldAllowed: false, mValues: data1=somebody1#android.com, mValuesBackReferences: null, mSelectionArgsBackReferences: null]

First, you have a try without a catch, which may explain why you don't see any error in the logs.
Second, from what I can see in the documentation, I think you should better write it this way:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.clear();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + "=?",
new String[] {String.valueOf(id)})
.withValue(ContactsContract.CommonDataKinds.Email.DATA, "somebody1#android.com")
.build());
try {
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}

Try use inside withValue not string, but array of strings.
.withValue(ContactsContract.CommonDataKinds.Email.DATA, emails)
where
String[] emails = {"Email Name<somebody1#android.com>"};

Related

android add custom field to all contacts

I'm trying to add my application icon to all existing contacts . my intent is to get contact by tapping user on my application icon to open app and send this contact to cloud. i could create contact by application and add my app MimeType to this and get save contact but i want to update all existing contact with my app icon this is my code that inserts my app mimeType to all contacts but it doesn`t work
Cursor cursor = context.getContentResolver().query(Data.CONTENT_URI, new String[] { Data.RAW_CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.CONTACT_ID },
null,
null,
null);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
do {// get id of contact and update all contact
id = cursor.getInt(0);
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, id)
.withValue(ContactsContract.Data.MIMETYPE, MIMETYPE)
.withValue(Data.DATA1, "profile1")
.withValue(Data.DATA2, "profile2")
.withValue(Data.DATA3, "profile3")
.build());
try {
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e1) {
e1.printStackTrace();
Log.i("Error =>>" + e1.getMessage());
}
while(cursor.moveNext())
and please help me!thanks
You can check this link. There's helpful example.
https://github.com/nemezis/SampleContacts/tree/master/src/com/nemezis/sample/contacts

DIRTY in RawContacts Android

I'm new in Android and O'm trying to understand how the contacts is working on Android so please bear with me.
I implemented an Observer to observe this URI, ContactsContract.Contacts.CONTENT_URI or ContactsContract.RawContacts.CONTENT_URI.
I am getting notified, and then I query the RawContact like below to get the dirty fields,
Cursor cursor = contResv.query(ContactsContract.RawContacts.CONTENT_URI,
null, ContactsContract.RawContacts.DIRTY + " = ?", new String[] { "1" }, null);
and I do get the accounts that have been changed (Version changed) or deleted. But what I have noticed is that after few seconds I'm getting notified again but this time the dirty rows that I have been notified about in the first time are removed, the DIRTY seems to be cleared after some Sync or something.
How can I guarantee that I will get the dirty rows before it's getting updated?
Because I'm afraid that if my app restarted for some reason and then came back up and then got notified, it won't get the dirty rows as it got cleared during the restart, or any other race condition scenario.
Edit 1
After digging for few hours I think I will need to create a raw contact with the same display name. The reason for this is that I think if I do this Android will think that I'm a sync adapter and will make this raw contact entry dirty and it want be cleaned unless I do so.
I'm trying this but it's not working, taken from here
private void addContact(String accountName, String accountType,
String name, String username) {
Log.i(Commons.TAG, "Adding contact: " + name);
ArrayList operationList = new ArrayList();
ContentProviderOperation.Builder builder = ContentProviderOperation .newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, null);
builder.withValue(RawContacts.ACCOUNT_TYPE, null);
//builder.withValue(RawContacts.SYNC1, username);
operationList.add(builder.build());
builder = ContentProviderOperation .newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference( ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
builder.withValue( ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
operationList.add(builder.build());
try {
ContentResolver mContentResolver = ContactsUpdateService.this.getContentResolver();
mContentResolver.applyBatch(ContactsContract.AUTHORITY, operationList);
} catch (Exception e) {
Log.e(Commons.TAG, "Something went wrong during creation! " + e);
e.printStackTrace();
}
}
This one didn't help also
private void addContact(String accountName, String accountType,
String name, String username) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, accountType)
.withValue(RawContacts.ACCOUNT_NAME, accountName).build());
ops.add(ContentProviderOperation
.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, name)
.withValue(Phone.NUMBER, "09876543")
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Deleting (Raw) Contacts in Android 2.x

I am working on Unit Tests for my Android app, and am doing a lot with Contacts. I have to insert contacts into the Android Content Providers, and delete them after running my tests. Trouble is, they do not get actually deleted:
Insertion:
ArrayList<ContentProviderOperation> contactOps = new ArrayList<ContentProviderOperation>();
int backRefIndex = 0;
Random r = new Random();
contactOps.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
contactOps.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRefIndex)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "Sample Name" + r.nextInt())
.build());
contactOps.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRefIndex)
.withValue(ContactsContract.CommonDataKinds.Phone.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "020" + r.nextInt())
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, r.nextInt(20)
.build());
try {
ContentProviderResult[] result = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, contactOps);
} catch (Exception e) {
e.printStackTrace();
}
Deletion method 1 (returns number of raw contacts, but they do not actually get deleted):
int deletedRawContacts = context.getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts._ID + " >= ?", new String[]{"0"});
Deletion method 2 (same result as deletion method 1, but different approach):
private static int deleteAllRawContacts(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor cur = cr.query(ContactsContract.RawContacts.CONTENT_URI, null, null, null, null);
int count = 0;
while (cur.moveToNext()) {
try {
String contactId = cur.getString(cur.getColumnIndex(ContactsContract.RawContacts._ID));
count += cr.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts._ID + " = ?", new String[]{contactId});
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
}
return count;
}
The deletion method for Contacts works, but the deletion method for Raw Contacts will return a false value. It will "tell" me, that it deleted all contacts, but when I run my next test case, the old Raw Contacts can still be found (i.e. the count of inserted contacts vs. present contacts is wrong). Note: All testing is done on the Android emulator.
Any ideas how to solve this?
I saw a similar question here: How to delete a contact? - but the solution does not seem to solve the given problem either.
As wiseideal already mentioned the way you delete your rawcontacts will only set the "deleted"-flag to 1.
What you need to do is to set the caller_is_syncadapter-flag in your URI to true like this:
RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build()
And then use this new URI to call the delete-method:
int deletedRawContacts = context.getContentResolver().delete(RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build(), ContactsContract.RawContacts._ID + " >= ?", new String[]{"0"});
The corresponding part in the documentation is here (Operations->delete).
Hope this helps and happy coding :)
I am working on the same issue.I found the delete column is setted to 1 once I "delete" it.So I think contentresolver doesnt delete the rawcontact data physically,it just set a delete flag.Maybe we should avoid these tag.

Set SEND_TO_VOICEMAIL on Android contacts

I'm trying to modify the value of SEND_TO_VOICEMAIL from 0 to 1 and vice versa.
I succeed to modify the others contact's details, such as name, number, nickname, email, ecc... but I need to change SEND_TO_VOICEMAIL.
I tried many possibility, but this should work... i guess:
String rawContactId = "1";
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(
ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection( Data.RAW_CONTACT_ID + "=?" , new String[] { rawContactId })
.withValue(ContactsContract.RawContacts.SEND_TO_VOICEMAIL , 1)
.build()
);
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
but the logcat says:
ERROR/AndroidRuntime(822): android.database.sqlite.SQLiteException: no
such column: send_to_voicemail: , while compiling: UPDATE data SET
send_to_voicemail=? WHERE _id =?
I really don't know what to try anymore. Any help would be really appreciated.
Thanks.
According to the[manual, the SEND_TO_VOICEMAIL field you're looking for isn't in the ContactsContract.Data table but in the ContactsContract.Contacts table. It seems like you're trying to modify the wrong table.
See ContactsContract.Data and ContactsContract.Contacts for the fields in each table.
It is better modify through ContentProvider Contacts.CONTENT_URI:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Contacts.CONTENT_URI)
.withSelection(Contacts._ID + "=?", new String[]{hmout.get("cid").toString()})
.withValue(Contacts.SEND_TO_VOICEMAIL, 1)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.e("Exception: ", e.getMessage());
}

Want to create a new group in contacts programmatically

I want to create a new contact group. I can query the group and display all the group names but I can't create a group in android I tried as creating contacts method but not created...
ContentResolver cr = this.getContentResolver();
groupValues = new ContentValues();
Log.e("Group","start");
groupValues.put(android.provider.Contacts.GroupMembership.GROUP_ID, 4);
groupValues.put(android.provider.Contacts.GroupMembership.NAME, "Sriseshaa");
groupValues.put(android.provider.Contacts.GroupMembership.PERSON_ID, 1);
cr.insert(android.provider.Contacts.GroupMembership.CONTENT_URI, groupValues);
i found the answer.i found in two ways but i dont know which is correct or best way to use.i am sharing those here..
its simple way like adding contact,
ContentValues groupValues;
create group()
{
ContentResolver cr = this.getContentResolver();
groupValues = new ContentValues();
groupValues.put(ContactsContract.Groups.TITLE, "MyContactGroup");
cr.insert(ContactsContract.Groups.CONTENT_URI, groupValues);
}
Another method using ContentProviderOperation
private void createGroup() {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(ContactsContract.Groups.CONTENT_URI)
.withValue(ContactsContract.Groups.TITLE, "SRI").build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
Thanks
adithi's answer is enough for Android 4.2.2, in which the name of Contacts manager application is "Contacts" , but the group created by that code will not show on Android 4.4,6 in which the name of Contacts manager application is "People".
The group would show up after adding the account type/name information while insertion happens.
private void createGroup() {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(ContactsContract.Groups.CONTENT_URI)
.withValue(
ContactsContract.Groups.TITLE,
Constants.CC_CONTACT_GROUP_TITLE)
.withValue(
ContactsContract.Groups.ACCOUNT_TYPE,
Constants.CC_CONTACT_GROUP_ACCOUNT_TYPE)
.withValue(
ContactsContract.Groups.ACCOUNT_NAME,
Constants.CC_CONTACT_GROUP_ACCOUNT_NAME)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
Why are you specifying group ID with groupValues.put(android.provider.Contacts.GroupMembership.GROUP_ID, 4); Its androids job to determined the group ID, you cant specify it because you don't know whether this id is already taken or not.

Categories

Resources