I'm trying to insert the contacts with their content uri Contacts.CONTENT_URI
I just declaring the following code for inserting the valuse : -
public void runContact()
{
Uri u = Contacts.CONTENT_URI;
ContentValues initialValues = new ContentValues();
initialValues.put("data1", "1234567890");
initialValues.put("data2", "Emergency");
initialValues.put("data3", "Number");
cr.query(u, null, null, null, null);
Cursor cursor1 = getContentResolver().query(u, null, null, null, null);
if (cursor1.moveToFirst())
{
do {
if((cursor1.getString(cursor1.getColumnIndex("address"))).equalsIgnoreCase("9953834074111"))
{
String data1 = cursor1.getString(cursor1.getColumnIndex("data1"));
String data2 = cursor1.getString(cursor1.getColumnIndex("data2"));
String data3 = cursor1.getString(cursor.getColumnIndex("data3"));
Log.v("data1",data1);
Log.v("data2",data2);
Log.v("data3", data3);
}
} while (cursor1.moveToNext());
}
}
Whenever i called this method, it returns an exception like this -
java.lang.IllegalArgumentException: URI: content://contacts, calling user: com.android.data, calling package:com.android.data
Why this happened? What i'm doing wrong in that code? Anyone guide me?
Try like below code:
private void addContacts(){
try
{
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (c != null) {
while (c.moveToNext()) {
if (c.getString(c.getColumnIndex(Phone.DISPLAY_NAME)).equalsIgnoreCase(officeText.getText().toString())) {
Log.d("ContactUSActivity", "Number Exist");
Toast.makeText(ContactUsActivity_2_0.this,getResources().getString(R.string.contact_already_exist),Toast.LENGTH_SHORT).show();
return;
}
}
}
ArrayList<ContentProviderOperation> contentProviderArray = new ArrayList<ContentProviderOperation>();
Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI);
builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,null);
builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME,null);
ContentProviderOperation contentProvider = builder.build();
contentProviderArray.add(contentProvider);
contentProviderArray.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,0)
.withValue(ContactsContract.Data.MIMETYPE,StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, officeText.getText().toString())
.build());
contentProviderArray.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, Phone.TYPE_MOBILE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneText.getText().toString())
.build());
contentProviderArray.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY,addressText.getText().toString())
.build());
/*contentProviderArray.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.,addressText.getText().toString())
.build()); */
getContentResolver().applyBatch(ContactsContract.AUTHORITY, contentProviderArray);
Toast.makeText(ContactUsActivity_2_0.this,getResources().getString(R.string.contact_added),Toast.LENGTH_SHORT).show();
}
catch (OperationApplicationException e) {
Toast.makeText(ContactUsActivity_2_0.this,getResources().getString(R.string.contact_failed_to_added),Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
Toast.makeText(ContactUsActivity_2_0.this,getResources().getString(R.string.contact_failed_to_added),Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Related
im trying to add new contacts to the phone but he does only the first 12 items.
i want to try all current 36 items and maybe more add to the phone contacts.
while ((line = bufferedReader.readLine()) != null) {
System.out.println("[[DEBUG]] [DW-UPDATE] LINE: " + line);
String[] split = line.split(";", -1);
split[2] = split[2].replace("/", "").replace("-", "");
if (!contactExists(mActivity, split[2])) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DISABLED)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, Integer.valueOf(split[0]))
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, split[1])
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, Integer.valueOf(split[0]))
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, split[2])
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
.build());
try {
mActivity.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}
}
}
function contactExists:
public boolean contactExists(Activity _activity, String number) {
Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] mPhoneNumberProjection = { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup.DISPLAY_NAME };
Cursor cur = _activity.getContentResolver().query(lookupUri, mPhoneNumberProjection, null, null, null);
try {
if (cur.moveToFirst()) {
return true;
}
} finally {
if (cur != null)
cur.close();
}
return false;
}// contactExists
what i must do, to work this better?
Your problem is with your back references when adding the additional contact data. The back reference should refer to the position of your RawContacts.CONTENT_URI insert within your list of operations (ops), not the position of the contact within your raw data file. You can fix this by keeping track of the size of ops through each iteration:
if (!contactExists(mActivity, split[2])) {
int backRef = ops.size();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(...)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRef)
.withValue(...)
.build()
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRef)
.withValue(...)
.build());
try {
mActivity.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}
}
I am trying to listen to the changes of Contacts. So I tried with one contact first. I have registered a Contact with my app ACCOUNT_TYPE. And trying to listen changes of that particular contact only. whenever there is a change in the Contact ContactsContract.RawContacts.VERSION should get incremented and ContactsContract.RawContacts.DIRTY should become 1. but nothing is getting changed. I am modifying contact in default phone contacts app.
Here is how I am registering contact
ContactsManager.addContact(this,new MyContact("1000","961820018","sandwitch"));
addContact Code:
public static void addContact(Context context,MyContact contact){
ContentResolver resolver = context.getContentResolver();
boolean mHasAccount = isAlreadyRegistered(resolver, contact.Id);
if(mHasAccount){
Log.d("Contact already","there");
} else {
Log.d("new Contact","Adding");
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// insert account name and account type
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, Constants.ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE,
ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.build());
// insert contact number
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.number)
.build());
// insert contact name
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.name)
.build());
// insert mime-type data
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, MIMETYPE)
.withValue(ContactsContract.Data.DATA1, 12345)
.withValue(ContactsContract.Data.DATA2, "user")
.withValue(ContactsContract.Data.DATA3, "MyData")
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}
}
}
this is how I am reading the changes with check VERSION
private void readUpdate(){
Cursor cursor = mContentResolver.query(ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.VERSION, ContactsContract.RawContacts.CONTACT_ID,ContactsContract.RawContacts.ACCOUNT_TYPE},
ContactsContract.RawContacts.ACCOUNT_TYPE+"=? ",
new String[]{String.valueOf(Constants.ACCOUNT_TYPE)},
null);
if (cursor != null && cursor.getCount() >0)
{
cursor.moveToFirst();
while(!cursor.isAfterLast()){
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID));
String version = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.VERSION));
String type = cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE));
if(id!=null && dirty!=null&& type!=null){
Log.d("Upadte version",version);
Log.d("Update ACCountid",id);
Log.d("Update type", type);
Cursor cur = mContentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
new String[]{String.valueOf(id)},
null);
if(cur!=null && cur.getCount()>0) {
cur.moveToFirst();
while(!cur.isAfterLast()){
String name = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d("Update Name", name);
Log.d("Update Number", number);
/* ContactsManager.updateContact(getContext(), id, name, number);
CV.clear();
CV.put(DBconstants.TableConstants.PHONE_NUMBER, number);
CV.put(DBconstants.TableConstants.C_CONTACT_NAME, name);
DB.updateInformation(DB, DBconstants.TableConstants.TABLE_CONTACTS, CV, DBconstants.TableConstants.C_ID, id);
CV.clear();
*/ cur.moveToNext();
}
cur.close();
}else{
Log.d("update", "nullinvalues");
}
}else{
Log.d("update", "nullvalues");
}
cursor.moveToNext();
}
cursor.close();
}else {
Log.d("update", "nullcursor");
}
}
I have a piece of code which updates the an Android contact´s image, the problem is that it doesn't work when the contact has no previous image. I also checked that the contact was from "Phone" account or "*#gmail.com" account. When it already has an image with these accounts I have no problem updating the image, the problem is just when the contact has no previous image assigned.
Here is the method in charge of updating the image.
public void update(long id, Bitmap bitmap) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// Picture
try
{
ByteArrayOutputStream image = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
ops.add(builder.build());
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
this.context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e)
{
e.printStackTrace();
}
}
And here is how I know if the contact belongs to one of the two accounts I mentioned above:
// Getting the raw contact id
public static int getRawContactId(Context context, long id) {
String[] projection = new String[] { ContactsContract.RawContacts._ID };
String selection = ContactsContract.RawContacts.CONTACT_ID + "=?";
String[] selectionArgs = new String[] { String.valueOf(id) };
Cursor c = context.getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI, projection,
selection, selectionArgs, null);
int rawContactId = -1;
if (c.moveToFirst()) {
rawContactId = c.getInt(c
.getColumnIndex(ContactsContract.RawContacts._ID));
}
return rawContactId;
}
Here I get the account name for further analysis
//...
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
String[] rawProjection = { RawContacts._ID, RawContacts.ACCOUNT_NAME };
Cursor raw = context.getContentResolver().query(rawContactUri, rawProjection, null, null, null);
if (raw.moveToFirst()) {
account = raw.getString(1);
}
Thanks in advance.
The problem seems to be that, as you describe, you're updating the image
http://developer.android.com/reference/android/content/ContentProviderOperation.html#newUpdate(android.net.Uri)
instead of inserting a new one
http://developer.android.com/reference/android/content/ContentProviderOperation.html#newInsert(android.net.Uri)
If the contact doesn't has a previous image, it's impossible to update the field in the database because it doesn't exists. You should perform an insert operation instead.
It's debatable if the api method should fail hard throwing an exception at runtime.
Hope it helps.
After some research as suggested I found an approach that works just fine.
https://stackoverflow.com/a/15145256/2423274
Here is the relevant part:
// Create new photo entry
int rawContactId = -1;
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {id}, null);
if(cursor.moveToFirst()) {
rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
if(rawContactId > -1) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photoBytes)
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
e.printStackTrace();
}
I create an Application to Read, Update, Delete Contacts Details.
Here is a problem to updating Contact_Image.
When new contact Added by device outside the Application without image.
then we can't update contact Image.
My Updating Code is.
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data.CONTACT_ID+"= ? AND "+ContactsContract.Data.MIMETYPE+"=?",new String[]{id,ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, imageInByte)
.build());
Please provide Solution Regard this.
You will have different code for updating a photo then adding a photo to a contact that doesn't have one. From your description above I believe you are trying to insert an image and not update an image, but here is code for both:
if(hasPhoto(resolver, id) == true)
{
int photoRow = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " = " + id + " AND " + ContactsContract.Data.MIMETYPE + " =='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, where, null, null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoRow = cursor.getInt(idIdx);
}
cursor.close();
// Update current photo
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data._ID + " = ?", new String[] {Integer.toString(photoRow)})
.withValue(ContactsContract.Data.RAW_CONTACT_ID, id)
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.DATA15, photoBytes)
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
// Create new photo entry
int rawContactId = -1;
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {id}, null);
if(cursor.moveToFirst())
{
rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
if(rawContactId > -1)
{
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photoBytes)
.build());
try
{
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The difference being that if you are updating an existing photo you use the newUpdate function, but if you are inserting a photo to a contact that never had one you use newInsert
I'm trying to add some contacts from an xml file which have been serialize with Simple xml framework and there is a weird error :
ERROR/ContentProviderOperation(10727): mType: 1, mUri: content://com.android.contacts/data, mSelection: null, mExpectedCount: null, mYieldAllowed: false, mValues: data1=Karl Koffi Marx Antoine Carter mimetype=vnd.android.cursor.item/name, mValuesBackReferences: raw_contact_id=1, mSelectionArgsBackReferences: null
This is the code
ContactList contactList = serializer.read(ContactList.class, xmlFile);
int nbreContacts = contactList.contact.length;
for(int i=0;i<nbreContacts;i++)
{
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
id = contactList.contact[i].getId();
name = contactList.contact[i].getName();
addName(Integer.parseInt(id), name);
flush(c);
}
private void addName(int contactId, String displayName)
{
if(displayName != null)
{
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, contactId)
.withValueData.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
.build());
}
}
private void flush(Context c)
{
ContentResolver cr = c.getContentResolver();
try
{
cr.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (RemoteException e)
{
Log.e("Writing", "Remote Error writting data ", e);
}
catch (OperationApplicationException e)
{
Log.e("Writing", "OAE Error writting data", e);
}
}
Any help would be appreciate.
Thanks to #Reno on the chat room.
withValueBackReference(Data.RAW_CONTACT_ID, contactId) changed to .withValueBackReference(Data.RAW_CONTACT_ID, 0)
I first thought RAW_CONTACT_ID was refering to the contact id that's why I was wrong. Problem solved and hope that will help someone else :)