I use following code for new contacts added to phone.
private static void addContact(Account account, String name, String username,String phone,String email) {
Log.i(TAG, "Adding contact: " + name);
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
builder.withValue(RawContacts.SYNC1, username);
operationList.add(builder.build());
//NAME adding area
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());
// Phone Number adding area
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
operationList.add(builder.build());
}
This code work fine for adding a new contact.
I want to update my contacts from server to phone. So I need contact id for updating purpose.
Can I get contact id from above code?. If anybody known share your answer.
If any questions or comments also welcome. Thanks for your answers.
Try this code,
ContentProviderResult[] res = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Uri myContactUri = res[0].uri;
int lastSlash = myContactUri.toString().lastIndexOf("/");
int length = myContactUri.toString().length();
int contactID = Integer.parseInt((String) myContactUri.toString().subSequence(lastSlash+1, length));
I hope this code help you..
The bulk insert that you do with the operation list will return a list of results (URIs I think, but it's been a few months since I did this), I believe you can get the ID you want from the first of these results
long rawContactId = ContentUris.parseId(rawContactUri);
After Applying the badge and receive the last segment you receive:
ContactsContract.RawContacts._ID
If you want to get Contact_id you should make this query:
(rowId - is the last segment you received before)
String[] projections = new String[]{ContactsContract.RawContacts.CONTACT_ID};
String select = ContactsContract.RawContacts._ID + "= ?";
String[] selectionArgs = new String[]{rowId};
Cursor cursor = context.getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projections, select, selectionArgs, null);
String contactId = null;
if (cursor.getCount() == 0) {
Log.d("aaa","Couldn't find row: " + rowId);
return null;
}
if (cursor.moveToNext()) {
int columnIndex;
columnIndex = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
if (columnIndex == -1) {
Log.d("aaa","Couldn't get contact id");
} else {
contactId = cursor.getString(columnIndex);
}
}
cursor.close();
return contactId;
Related
I am successfully adding a contact to a group using the raw_contact_id using this method
public static Uri addContactToGroup(String rawContactId,String groupId)
{
try
{
ContentValues values = new ContentValues();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(GroupMembership.GROUP_ROW_ID, groupId);
values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
return getContentResolver().insert(Data.CONTENT_URI, values);
}
catch (Exception e)
{}
return Uri.EMPTY;
}
But i want to add a contact using the name. I tried with some changes but not working. Please help Thanks!
Simple, just query for all RawContacts by that name, and add them to the group using your code:
public void addToGroupByName(String name, long groupId) {
String[] projection = new String[] { Data.RAW_CONTACT_ID };
String selection = "(" + Data.MIMETYPE + "=?) AND (" + StructuredName.DISPLAY_NAME + "=?";
String[] selectionArgs = new String[] { StructuredName.CONTENT_ITEM_TYPE, name };
Cursor cur = contentResolver.query(Data.CONTENT_URI, projection, selection, null, null);
while (cur != null && cur.moveToNext()) {
long rawId = cur.getLong(0);
addContactToGroup(rawId, groupId);
}
if (cur != null) {
cur.close();
}
}
Notes:
RawContact ID is a long, not a string
Group ID is a long as well
Since a name is not a unique identifier, and a user may have more then one contact with the same name, this code may have unexpected consequences, so make sure you know what you're doing
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 added some raw contacts to an account I created.
Does anyone knows how can I access its data fields?
This is how I added the contact:
Log.i(TAG, "Adding contact: " + username);
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
// create the contact
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
builder.withValue(RawContacts.SYNC1, username);
operationList.add(builder.build());
// set display name
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());
// set profile data
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.net.myapp.android.profile");
builder.withValue(ContactsContract.Data.DATA1, username);
builder.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name) + " Profile");
builder.withValue(ContactsContract.Data.DATA3, "View profile");
operationList.add(builder.build());
The cursor I use to get my contacts is:
private Cursor getContactsCursor(CharSequence constraint) {
Uri uri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME, getString(R.string.app_name)).appendQueryParameter(RawContacts.ACCOUNT_TYPE, getString(R.string.ACCOUNT_TYPE)).build();
String[] projection = null;//new String[] { ContactsContract.Contacts.DISPLAY_NAME };
String selection = null;
if (constraint != null && constraint.length() > 0)
selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE '%" + constraint + "%'" ;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor cursor = getContentResolver().query(uri, projection, selection, null , sortOrder);
return cursor;
}
Unfortunately, I need Data1 field, which is not one of the cursor columns.
I guess that the problem is with RawContacts.CONTENT_URI Uri.
What should I use instead?
I am trying to insert a contact through my application but i am not able to figure out what should be the value of accountType and accountName as below.
ContentValues values = new ContentValues();
values.put(RawContacts.ACCOUNT_TYPE, accountType);
values.put(RawContacts.ACCOUNT_NAME, accountName);
Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
values.put(StructuredName.DISPLAY_NAME, "Mike Sullivan");
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER,"1-800-111-411");
getContentResolver().insert(Data.CONTENT_URI, values);
Also when i try to execute this code with the following changes in the accountType and accountName, i am unable to see it in the Contacts.
values.put(RawContacts.ACCOUNT_TYPE, "acc_type");
values.put(RawContacts.ACCOUNT_NAME, "acc_name");
But it seems that some values get inserted as when i search for "Mike Sullivan" i get the contact but without the Phone Number.
Please Help
below is the code to add contact database and also it return whether the contact was added or not::::
//to save contact in Database
public boolean SaveContact(Activity _activity,String name,String number) {
String MIMETYPE_RADUTOKEN = "vnd.android.cursor.item/radutoken";
String szname = name,szMobile = number;
//Create a new contact entry!
String szToken = String.format("RADU_TOKEN_%d", System.currentTimeMillis());
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).withValue(RawContacts.ACCOUNTTYPE, null).withValue(RawContacts.ACCOUNT_NAME, null).build());
//INSERT NAME
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,rawContactInsertIndex).withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, szname).build());
//INSERT PINLESSMAX MOBILE NUMBER
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, szMobile).withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM).withValue(ContactsContract.Data.DATA3, "PinLessMax").build());
// SAVE CONTACT IN BCR Structure
Uri newContactUri = null;
//PUSH EVERYTHING TO CONTACTS
try{
ContentProviderResult[] res = _activity.getContentResolver().applyBatch(ContactsContract.AUTHORITY,ops);
if (res!=null && res[0]!=null) {
newContactUri = res[0].uri;
}
}catch (RemoteException e) {
// error
newContactUri = null;
} catch (OperationApplicationException e) {
// error
newContactUri = null;
}
if (newContactUri == null) {
return false;
}
boolean foundToken = false;
// IDENTIFY Contact based on name and token
String szLookupKey = "";
Uri lkup = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, szname);
ContentResolver cr = _activity.getContentResolver();
Cursor idCursor = _activity.getContentResolver().query(lkup, null, null, null, null);
// get all the names
while (idCursor.moveToNext()) {
String szId = idCursor.getString(idCursor.getColumnIndex(ContactsContract.Contacts._ID));
String szName = idCursor.getString(idCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
szLookupKey = idCursor.getString(idCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
// for this contact ID, search the custom field
String tokenWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] tokenWhereParams = new String[]{szId, MIMETYPE_RADUTOKEN};
Cursor tokenCur = cr.query(ContactsContract.Data.CONTENT_URI, null, tokenWhere, tokenWhereParams, null);
while (tokenCur.moveToNext()) {
String token = tokenCur.getString(tokenCur.getColumnIndex(ContactsContract.Data.DATA1));
// CHECK THE TOKEN!
if (szToken.compareTo(token) == 0) {
tokenCur.close();
foundToken = true;
break;
}
}
tokenCur.close();
if (foundToken) break;
}
idCursor.close();
return true;
}//SaveContact()
You can give null values for account type and account name if you do not want to create the contact under a specific account
values.put(RawContacts.ACCOUNT_TYPE, null);
values.put(RawContacts.ACCOUNT_NAME, null);
In most of the devices it creates as a default phone contact.
If you want to know all the account types available in the device,
You can use the following code
Account[] accountList = AccountManager.get(this).getAccounts();
for(int i = 0 ; i < accountList.length ; i++) {
System.out.println(accountList[i].type);
}
Note: Different OEMs uses different name for account type.
sample contacts:
_ID DISPLAY_NAME PHONE
1 contact1 11111111
2 contact2 22222222
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("22222222"));
Cursor c = this.getContentResolver().query(uri, new String[] {Data._ID}, null, null, null);
long profileId = 0;
if (c.moveToFirst())
{
profileId = c.getLong(0);
}
c.close();
c = null;
final ContentValues values = new ContentValues();
if (profileId > 0) {
values.put(StatusUpdates.DATA_ID, profileId);
values.put(StatusUpdates.STATUS, "HELLO WORLD!");
values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_CUSTOM);
values.put(StatusUpdates.CUSTOM_PROTOCOL, CUSTOM_IM_PROTOCOL);
values.put(StatusUpdates.PRESENCE, 4); //
values.put(StatusUpdates.STATUS_RES_PACKAGE, this.getPackageName());
values.put(StatusUpdates.STATUS_LABEL, R.string.label);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(StatusUpdates.CONTENT_URI)
.withValues(values).build());
try{
this.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch(RemoteException e)
{Log.e...}
catch(OperationApplicationException e)
{Log.e...}
}
I'm trying to insert status to the specified contact "contact2", but it doesn't work correctly, and always insert to "contact1".
Please help me, many thanks.
from sample sync adapter example :
public static long lookupRawContact(ContentResolver resolver, String userId)
{
long authorId = 0;
final Cursor c =
resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION,
UserIdQuery.SELECTION, new String[] {userId},
null);
try {
if (c.moveToFirst()) {
authorId = c.getLong(UserIdQuery.COLUMN_ID);
}
} finally {
if (c != null) {
c.close();
}
}
return authorId;
}
This will return the correct profile ID or 0 if not found