I'm backing up and restoring contacts, I'm able to do it, but while aggregation of rawcontacts for linked contacts(joined contacts) using ContactsContract.AggregationExceptions
If i join 3 contacts, say Contact A (master) and Contact B (linked) and C (linked)
I do the backup ,and restore,for the newly created id's with correct mapping, I'm updating the ContactsContract.AggregationExceptions.CONTENT_URI with following code:
private boolean aggregateContactLinks() {
ContentResolver cr = context.getContentResolver();
int listCount = linkList.size();
ContentValues values = new ContentValues(3);
Log.i(tag, "aggregating contacts");
for (int i=0; i<listCount; i++) {
values.put(AggregationExceptions.RAW_CONTACT_ID1,
linkList.get(i).newId1);
values.put(AggregationExceptions.RAW_CONTACT_ID2,
linkList.get(i).newId2);
values.put(AggregationExceptions.TYPE,
AggregationExceptions.TYPE_KEEP_TOGETHER);
Log.i(tag," new master id(id1) :"+linkList.get(i).newId+"\nlinkid2 :"+newId2);
Log.i(tag,
"result :"
+ cr.update(AggregationExceptions.CONTENT_URI,
values, null, null));
Log.i(tag, "\nupdated one contact");
}
values.clear();
return true;
}
output , on phone i can see the linked content but in display name of contact is c instead of a
before backup
after backup, deleting the contacts and after restore
can anyone know where exactly im going wrong,thanks in advance
If you want to tell Android contact provider that it should use the specific raw contact name for aggregated contact (not display names of linked contacts B and C but the display name of master contact A), you may use RawContactsColumn.NAME_VERIFIED. Simply set it to "1" for your master raw contact after updating aggregation exceptions.
I found this trick in the standard Contacts application's
code:
// Mark the original contact as "name verified" to make sure that the contact
// display name does not change as a result of the join
if (verifiedNameRawContactId != -1) {
Builder builder = ContentProviderOperation.newUpdate(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, verifiedNameRawContactId));
builder.withValue(RawContacts.NAME_VERIFIED, 1);
operations.add(builder.build());
}
RawContactsColumn interface is protected, so you should use "name_verified" as column name. Because of the fact that RawContactsColumn isn't open, maybe you should also check if "name_verified" column exists before updating to avoid crashes.
Related
I am maintaining a list of contacts for my application. First I pick contact using ACTION_PICK with an intent. I am saving these contacts in my local database along with CONTACT_ID. Now user may choose to edit any contact to add some extra information that my app needs. I fire that edit intent with ACTION_EDIT. I have two questions here
I am saving CONTACT_ID to my database in order to use in edit intent. First question is does this id changes after edition ? because It so happens that I am unable to open contact editor for same contact again.
Second question is how can I read back all the details of this edited contact ? I am getting this back in my onActivityResult(). I have tried to use same code which i am using in case of picking but data structure returned in case of edit is different it seems.
you can get any data from contacts using a cursor like
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID};
// query time
Cursor cursor = _context.getContentResolver()
.query("ContactsContract.Contacts.CONTENT_URI",
projection, null, null, null);
if(cursor != null) {
while ( cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(
ContactsContract.PhoneLookup.DISPLAY_NAME));
// do other stuff
}
}
cursor.close();
take a look at https://developer.android.com/training/contacts-provider/retrieve-details.html
hello~ when we delete contacts in android, android just sets raw_contacts.deleted=1. All data of the deleted contact can be found in the table "data" by SQLiteAdmin or other tools.
I want to load these deleted contacts' data, but it doesn't work.codes are as foloowed:
private void restoreContactsData() {
Uri idUri=Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri=Uri.parse("content://"+ContactsContract.AUTHORITY+"/data");
Cursor c=cr.query(idUri, new String[]{"_id"}, "deleted=1", null, null);
StringBuilder sb=new StringBuilder();
while(c.moveToNext()){
int deletedRawContactId=c.getInt(0);
sb.append("rawId="+deletedRawContactId).append("\n\t");
Cursor dataCursor=cr.query(dataUri,
new String[]{"data1"},
"row_contact_id="+deletedRawContactId,
null,
null);
while(dataCursor.moveToNext()){
String phone=dataCursor.getString(0);
sb.append(phone).append("\n");
}
}
tv.setText(sb.toString());
}
I have tried to set the constant VISIBLE_CONTACTS_ONLY=false as parameter,but i wont' work either.
The method above can find the deleted raw_contact ids.BUT when I use these ids to query the "data" table , it return nothing.
If I pull the contacts2.db file out of emulator, I can find the data which are associated with the deleted raw_contact in the "data" table.
The question is ,whether can i restore these deleted data from contacts' contentprovider?
Thank you
Is there an accepted/received way of checking to see if a person (phone number) is in the Contact List?
I'm hoping there's something I can call like this:
bool bInContactList = InContactList("1415922353");
It is not as simple as you want but you can query a Contacts content provider for the contact associated with a phone number:
Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor c = getContentResolver().query(lookupUri, new String[] {PhoneLookup._ID}, null, null, null);
if (c.getCount() > 0) {
// there is some contact
} else {
// there is no contacts with phoneNumber
}
The application needs android.permission.READ_CONTACTS permission to access contacts data.
You can check Android Developer site for further references about content providers and android.providers package documentation for the list of available standard providers in Android.
I am afraid you did not provide enough information about the language you are talking about. If you use Java -for example- you have a contains method (common to all collections) so, if you want to know if a certain String is contained in a collection you could do it by invoking this method:
boolean found = someCollection.conmtains("1415922353");
This question should be a starting point to all of us who want to manipulate contacts in Android.
First things first
As I am aware, since API level 5 the Contacts API has changed, so in order to make the application work correct I need to check what android os is on the phone and if prior 5 use one content provider or else use the newer one. The only annoyance in this case is the warnings of deprecated I get. The application is build against Android 2.3.3 but needs to work from 1.5+
1. Querying contacts
This is the easiest part to do. Usually querying means getting data like Contact name, phones, picture, email and displaying it on a listview. For instance here is how I've done it in API prior 5
String[] projectionPeople = new String[] {People._ID, People.NAME,};
String[] projectionPhone = new String[] {Phones.NUMBER};
try {
// Get the base URI for People table in Contacts content provider.
// which is: content://contacts/people/
Uri contactUri = People.CONTENT_URI;
ContentResolver resolver = getContentResolver();
Cursor phonesCursor = null;
Cursor peopleCursor = resolver.query (contactUri,
projectionPeople, //Which columns to return.
"People.NAME is not null", // WHERE clause--we won't specify.
null, // Selection Args??
People.DEFAULT_SORT_ORDER); // Order-by name
if (peopleCursor != null && peopleCursor.getCount() >0)
{
// go to the beginning of the list
peopleCursor.moveToFirst();
do
{
//do something with current contact info
phoneUri= Uri.withAppendedPath(personUri, Contacts.People.Phones.CONTENT_DIRECTORY);
phonesCursor = resolver.query(phoneUri,
projectionPhone,
null,
null,
Phones.DEFAULT_SORT_ORDER);
if (phonesCursor!=null && phonesCursor.getCount()>0)
{
phonesCursor.moveToFirst();
lstPhones = new ArrayList<String>();
do
{
//add phone numbers to a List<String> for instance
} while (phonesCursor.moveToNext());
if (phonesCursor != null && !phonesCursor.isClosed())
phonesCursor.close();
} while (peopleCursor.moveToNext());
if (peopleCursor != null && !peopleCursor.isClosed())
peopleCursor.close();
}
}
catch (Exception ex)
{
}
}
Haven't tried it yet on the new api but the cursor should be like
final String[] projection = new String[] {
RawContacts.CONTACT_ID, // the contact id column
RawContacts.DELETED // column if this contact is deleted
};
final Cursor rawContacts = managedQuery(RawContacts.CONTENT_URI, // the URI for raw contact provider
projection
null, // selection = null, retrieve all entries
null, // selection is without parameters
null); // do not order
Sure, this needs to be elaborated a bit more, but it should provide the basics of simple query against Contacts content provider
2. Backup
My first thought on this was: if I know the Id of a Contact, I create tables in a sqlite database exactly how the cursor columns are and insert all the data into my tables. This is not an easy task as it requires a lot of codding not to mention that different apis have different table structures. What would be the best solution to backup one contact or multiple contacts ?
3. Delete
This should work on all apis using content providers, but data is spread on many packages and uris and I'm not sure from where to delete
4. Insert
After a contact is backed up, I may need to restore/insert it again. As in case of deletion, on which uris do I need to insert ?
Please, let's try to elaborate this issues so in the futures, who needs to use Contacts in Android apps could take this question as a solid starting point. Thank you stackoverflow community.
Here is a good starting point
http://developer.android.com/resources/samples/BusinessCard/index.html
I'm reading contact data from ContractContacts, and can lookup TIMES_CONTACTED (which is useful to me), but this field only applies to calls to that contact. I'm also interested in the number of times a contact has been contacted via SMS or email.
Does anyone know if this information is available? I've been searching but haven't come across anything.
For SMS, you'll want to access the inbox located at content://sms/inbox directly and perform a database query to count the number of rows corresponding to the matching contact.
Something like:
String personAddress = addressFromContact();
Uri smsUri = new Uri("content://sms");
if (smsUri != null) {
Cursor smsCursor = getContentResolver().query(smsUri, null, "address=?", new String[] {personAddress}, null);
int smsCount = smsCursor.getCount();
}