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
Related
I have added my app connection in Phonebook like Viber and Whatsapp do. I managed to open desired activity when connection is clicked in Phonebook. However I do not receive any contact related data in activity intent extras. Can you please help to get data about which contact connection was clicked in Phonebook?
This is how I add my custom mymetype:
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactId)
.withValue(ContactsContract.Data.MIMETYPE, mimetype)
.withValue(ContactsContract.Data.DATA1, "start my app")
.withValue(ContactsContract.Data.DATA2, "start my app")
.withValue(ContactsContract.Data.DATA3, "start my app")
.build());
I found out the answer by myself:
Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
String data1 = cursor.getString(cursor.getColumnIndex("DATA1"));
}
cursor.close();
}
I have made an contact application. I am able to delete contact from samsung and moto but in MI(XIOMI) unable to delete contact. It display popup with message "Contact can't delete by third party apps. My code
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
String[] args = new String[]{id};
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
.withSelection(ContactsContract.RawContacts.CONTACT_ID + "=?", args).build());
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException | OperationApplicationException e) {
}
Was the RawContact created on your app's Account using your SyncAdapter?
Anyway, try this:
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
rawContactUri = rawContactUri.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();
ContentProviderOperation.newDelete(rawContactUri).build();
I am trying to delete a contact from phone contacts. The contact gets deleted from phone contacts but it's not getting deleted from the server-side (Google contacts) and when the Google contact sync triggers then that deleted contact re-appears. Below is my code.
public static void deleteContact(long rawid, ContentResolver contentResolver) {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
Uri uri = ContactsContract.RawContacts.CONTENT_URI
.buildUpon()
.appendQueryParameter(
ContactsContract.CALLER_IS_SYNCADAPTER,
"true")
.build();
ops.add(ContentProviderOperation
.newDelete(uri)
.withSelection(
ContactsContract.RawContacts._ID + " = ?",
new String[]{Long.toString(rawid)})
.build());
try {
contentResolver.applyBatch(
ContactsContract.AUTHORITY,
ops);
} catch (RemoteException | OperationApplicationException e) {
e.printStackTrace();
}
}
You should try with ContactsContract.CALLER_IS_SYNCADAPTER as false in your code. While set to true, the contact is permanently deleted from the database. But when the next sync happens the contact is synched back. How Google sync checks for deleted contacts, is using a deleted flag which is set only if you set ContactsContract.CALLER_IS_SYNCADAPTER as false. Below is a snippet of code from the ContactsProvider class (contentprovider for contacts datastore)
if (callerIsSyncAdapter || rawContactIsLocal(rawContactId)) {
// When a raw contact is deleted, a SQLite trigger deletes the parent contact.
// TODO: all contact deletes was consolidated into ContactTableUtil but this one can't
// because it's in a trigger. Consider removing trigger and replacing with java code.
// This has to happen before the raw contact is deleted since it relies on the number
// of raw contacts.
db.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null);
count = db.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null);
mTransactionContext.get().markRawContactChangedOrDeletedOrInserted(rawContactId);
} else {
count = markRawContactAsDeleted(db, rawContactId, callerIsSyncAdapter);
}
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.
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.