I am trying to update existing contact's image using below code :
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{String.valueOf(rawContactId), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, stream.toByteArray());
ops.add(builder.build());
------
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
e.printStackTrace();
}
When contact have another images previously, then this code works fine. But when existing contact don't have any image, then this code not able to update that contact's image.
Please guide me , how to update an existing contact's (Contact which don't have any image previously) image.
Related
I am trying to Edit Specific Contact's display name, but whatever I do, display name is not getting edited. I have looked all related questions, but I did not find any solution regarding this issue.
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=? AND " +
ContactsContract.CommonDataKinds.Phone.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND "+ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID +"=?",
new String[]{id,raw})
//.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "B "+name)
//.withValue(ContactsContract.CommonDataKinds.Phone.PHONETIC_NAME, "B "+name)
//.withValue(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY, "B "+name)
//.withValue(ContactsContract.Data.DISPLAY_NAME, "B "+name)
.withValue(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, "B "+name)
.build());
try {
ContentProviderResult[] result =HomeActivity.this.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Log.e("Edit Result",result.toString());
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
I have tried all option which are written in comments, but with ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME. It edits contact No. instead of contact name. I am trying to do this for the last 3 days, but not getting success. Please tell me what I'm doing wrong or show me the right way of editing contact name.
The name is stored in contacts database with STRUCTURED_NAME mime type. More information here
You should modify your code like this
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=? AND " +
ContactsContract.CommonDataKinds.Phone.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.StructuredName + "' AND "+ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID +"=?",
new String[]{id,raw})
.withValue(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, "B "+name)
.build());
try {
ContentProviderResult[] result =HomeActivity.this.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Log.e("Edit Result",result.toString());
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
I would suggest that you pull out the contacts database from an emulator or a rooted phone to get a better understanding.
I am working on a application where i need to add my app link just like freecharge or whatspp in phone's existing contact profile without creating new.
I tried doing this with the following code
public static void addContactTag(Context context, String number) {
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
// Create our RawContact
ContentProviderOperation.Builder builder = ContentProviderOperation
.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, AccountGeneral.ACCOUNT_NAME);
builder.withValue(RawContacts.ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE);
operationList.add(builder.build());
// Create a Data record of common type 'Phone' for our RawContact
builder = ContentProviderOperation
.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number);
operationList.add(builder.build());
// Create a Data record of custom type
// "vnd.android.cursor.item/vnd.be.ourservice.profile" to display a link
// to our profile
builder = ContentProviderOperation
.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, MIMETYPE);
builder.withValue(ContactsContract.Data.DATA1, number);
builder.withValue(ContactsContract.Data.DATA3, "My app");
operationList.add(builder.build());
try {
context.getContentResolver().applyBatch(ContactsContract.AUTHORITY,
operationList);
Log.i("addContact batch applied");
} catch (Exception e) {
Log.i("Something went wrong during creation! " + e);
e.printStackTrace();
}
}
Everything seems fine but its not updating existing contact rather its creating a new one .
Any help will be appreciated.
Thanks in advance.
The code you mentioned here is meant to write a new contact.to edit a current contact you should do something like this.
try {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(ContactsContract.CommonDataKinds.Phone._ID + "=? AND " +
Data.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'",
new String[]{contact_id})
.withValue(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, "anything")
.build());
ContentProviderResult[] result = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.w("UpdateContact", e.getMessage()+"");
for(StackTraceElement ste : e.getStackTrace()) {
Log.w("UpdateContact", "\t" + ste.toString());
}
Context ctx = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(ctx, "Update failed", duration);
toast.show();
}
If you haven't figured this out yet, give that a go. I found updating contacts to be very tricky in getting the selection arguments right.
Accept and mark it up if this helps.
Happy coding :)
Am I the only one trying to achieve this ... :/ ?
In short:
I want to fetch back the picture of my contacts as they do defined it by themselves (on their Google own Account page for instance).
Use case: I have modified one of my contact's picture myself, and now, I want to undo that change -> I want to 'fetch back' the Google picture of my contact (the one set by him/herself).
I have an app that manage Google Contacts. It also manage contact photo using
ContactsContract.CommonDataKinds.Photo.PHOTO
And it's working fine.
Here is a scenario I would like to support:
I add a new contact in my contact list entering it's gmail address. (OK)
After a while, contact photo is available on my contact app (since contact has a picture on its Google account, AND contact sync is ON on the Android device). (OK)
Within my app, I change the app contact picture (so, I 'override' contact picture) (OK)
Within my app, I want to get back default Google contact picture: Not OK. How can I achieve that?
Please take a look at my code here to set the Photo.
Should I just 'clear' the photo and relies on ContactProvider to download back user photo from Google account?
How can I clear the photo. Set ContactsContract.CommonDataKinds.Photo.PHOTO to 'null'? and delete the associated file, i.e.,
Uri rawContactPhotoUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY)
Thanks for helping.
Here is how I update picture:
private void updatePhotoThumbnail(Bitmap bitmap, Contact contact) throws Exception
{
byte[] contactPhotoBytes = getContactPhotoBytes(bitmap);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// #formatter:off
String where = ContactsContract.RawContacts.ACCOUNT_NAME + "= ? "
+ "AND " + ContactsContract.RawContacts.ACCOUNT_TYPE + "= ? "
+ "AND " + ContactsContract.Data.CONTACT_ID + "= ? "
+ "AND " + ContactsContract.Data.RAW_CONTACT_ID + "= ? "
+ "AND " + ContactsContract.Data.MIMETYPE + " = ?";
// #formatter:on
String[] params = new String[]
{
// #formatter:off
_accountName,
AccountManagerHelper.GOOGLE_ACCOUNT_TYPE,
String.valueOf(contact.getId()),
String.valueOf(contact.getRawContactId()),
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
// #formatter:on
};
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(where, params)
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, contactPhotoBytes).build());
try
{
_contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
updateDisplayPhoto(contact.getRawContactId(), contactPhotoBytes);
}
catch (RemoteException e)
{
e.printStackTrace();
throw new Exception(e.getMessage());
}
catch (OperationApplicationException e)
{
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
private void updateDisplayPhoto(long rawContactId, byte[] photo)
{
Uri rawContactPhotoUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try
{
AssetFileDescriptor fd = getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
OutputStream os = fd.createOutputStream();
os.write(photo);
os.close();
fd.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Here is a tutorial to retrieve user's Google profile picture. It also retrieves some other things like account Email, name, ...
I think this is the straight way for your question :)
Stay in contact if it hepled.
I am working on the an application in which I want to update contact of particular person. When I update only contact first and last name then it working fine but I want to update full detail of contact like email address, number, postal addres etc.
Please provide me some useful link. Thanks in advance.
each field (email, name, adress) has its on mime type, which you should use
in order to update the field.
lets try to update the email for instance.
First, you should find the detail you want to update.
we will work with Data table, where each Data.RAW_CONTACT_ID represents a detail
about some contact.
So, we need to find the Data.RAW_CONTACT_ID where the id is the id of the contact you want
to edit.
Now we need to find the mimetype (the specific row which represents the detail) of
email (Email.CONTENT_ITEM_TYPE).
The data of an email is stored in the column Email.DATA - there we put the new email.
if you want a specific email type, you should add it to the query:
for example, if you want to add a home-email, then you should add Email.TYPE_HOME
to the query.
then we build a query and finally apply the change.
Here's an examle:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String emailParams = Data.RAW_CONTACT_ID + " = ? AND " + Data.MIMETYPE + " = ?";
String[] emailParamsWhere = new String[] { "contact_id", Email.CONTENT_ITEM_TYPE };
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI).withSelection(emailParams, emailParamsWhere).withValue(Email.DATA, "new email").withValue(Email.TYPE, Email.TYPE_HOME)
.build());
try
{
ContentProviderResult[] res = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (res != null)
{
return true;
}
return false;
}
catch (RemoteException e)
{
Log.d(TAG, e.getMessage());
e.printStackTrace();
}
catch (OperationApplicationException e)
{
Log.d(TAG, e.getMessage());
e.printStackTrace();
}
For updating mobile phone, use this query:
String phoneParams = Data.RAW_CONTACT_ID + " = ? AND " + Data.MIMETYPE + " = ? AND " + Phone.TYPE + " = " + Phone.TYPE_MOBILE;
String[] phoneParamsWhere = new String[] { "contact_id", Phone.CONTENT_ITEM_TYPE };
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI).withSelection(phoneParams, phoneParamsWhere).withValue(Phone.NUMBER, "mobile_number")
.withValue(Phone.TYPE, Phone.TYPE_MOBILE).build());
Hope I helped
i have a problem with my app ,
In egypt they are going to add extra digit to mobile numbers to expand , so i made an app to modify the existing numbers to the new one.
So basically i read all phone numbers , based on some conditions i manipulate them and save the new data,
Iam working on eclipse with adt plugin , i have tried the app on emulator 2.2 , and emulator 2.3 and is working very fine and modify all contacts.
but when i transfered on my mobile galaxy s android 2.3.5 , it runs without saving the new contact data , i even debugged to see the flow , it works normal gets all numbers modify them and save them without errors , but contacts are not updated.
Is there a certain reason , can you give me more ideas ?
i want to provide some more info , i have installed froyo 2.2 on my mobile and still won't save the new contact number , although it is working very good on the emulator, i save the contact this way :
ContentResolver cr2 = getContentResolver();
String where = Data.RAW_CONTACT_ID + " = ? AND "
+ String.valueOf(Phone.TYPE) + " = ? ";
String[] params = new String[] { id,
String.valueOf(type) };
ArrayList<ContentProviderOperation> ops=new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newUpdate(Data.CONTENT_URI)
.withSelection(where, params)
.withValue(
ContactsContract.CommonDataKinds.Phone.DATA,
phoneNumber).build());
try {
cr2.applyBatch(ContactsContract.AUTHORITY,ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ok Guys , Sorry iam just new to android , but i found the mistake and i modified the code to be :
ContentResolver cr2 = getContentResolver();
String where = Data.CONTACT_ID + " = ? AND " +Data.MIMETYPE + "='" +
Phone.CONTENT_ITEM_TYPE + "'" + " AND "
+ String.valueOf(Phone.TYPE) + " = ? ";
String[] params = new String[] { id,
String.valueOf(type) };
// Cursor phoneCur = managedQuery(Data.CONTENT_URI,
// null, where, params, null);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newUpdate(Data.CONTENT_URI)
.withSelection(where, params).withValue(
Phone.NUMBER,
phoneNumber).build());
try {
cr2.applyBatch(ContactsContract.AUTHORITY, ops);
count++;
System.out.println(phoneNumber);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
So Technincally i added the mimetype , and i used to update phone.data so i changed that also to phone.number , now it is working ok on 2.2 / 2.3.5 , so i guess this question is closed , but i have one more thing to ask , the read contacts doesn't include facebook or twitter contacts , is there anyway to read all contacts to update them all including facebook and twitter ????
You can do one thing: just change the project-properties file and edit target=android-10 and then try...