I am trying to maintain a contact database and get a callback for Add/Update/Delete as soon as something changes in the URI.
I have written a ContentObserver to observe on ContactsContract.Contacts.CONTENT_URI on contacts. I get a callback as soon as a contact changes and then I update my database by checking ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP.
While this works fine for add/update, it does does not work for deleting a contact.
I do not want to parse all the contacts that I have in memory and check against android database. That would take time and CPU.
I know there exists many question of these types but I am not able to figure out things specific to deleting the contact.
Does there exist a way to perform this ?
As I have posted in above comment as well, following code works for API level 18 and above.
You can query on a uri ContactsContract.DeletedContacts.CONTENT_URI to get the list of all the contacts that have been deleted.
My query looks like following :
String selection = ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + " > ?";
String[] selectionArgs = new String[]{String.valueOf(mLastContactDeleteTime)};
Cursor cursor = mContext.getContentResolver().query(ContactsContract.DeletedContacts.CONTENT_URI, null, selection, selectionArgs, null);
Related
My problem is that I try to disallow to native Android Contacts application to delete my application's contacts (which are specified by my application account type) from device.
For that I've specified my own SyncAdapter with it's own Service and it's meta-data described in syncadapter.xml. The value of supportsUploading is set to false (this way I say that contacts created by my application are read-only)
However, when I try to delete a contact of my application from standard Contacts app I get the message which says:
You can't delete contacts from read-only accounts, but you can hide
them in your contacts list
Everything seems fine until I try to get data of the contact which I previously deleted ("hide") from standard "Contacts" in my own application.
The returned cursor is null because there isn't any row in Data table associated with this contact's RAW_CONTACT_ID. I also check if the contact exists on the device looking for
it's DELETED flag value in RawContacts table and observed that it has been set to 1 which means that contact has been deleted.
As official documentation describes:
Some sync adapters are read-only, meaning that they only sync
server-side changes to the phone, but not the reverse. If one of those
raw contacts is marked for deletion, it will remain on the phone.
However it will be effectively invisible, because it will not be part
of any aggregate contact.
So the problem is that I can't display this contact's data in my application any more because I don't know how to retrieve them from contacts database. If somebody knows how to handle this situation I would appreciate any advice. Thanks
So after more meticulous search I found the way to retrieve data for any RAW_CONTACT in my application independently of was it deleted from some other application or not.
Using of RawContacts.Entity API does this job.
Previously I tried to retrieve contact's data using such logic:
public Cursor getContactData(long rawContactId) {
return getContentResolver().query(ContactsContract.Data.CONTENT_URI, null,
ContactsContract.Data.RAW_CONTACT_ID + "=" + rawContactId, null);
}
And this method always returned null for deleted contact.
But using RawContacts.Entity such way:
public Cursor getContactData(long rawContactId) {
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, id);
rawContactUri = Uri.withAppendedPath(rawContactUri, RawContacts.Entity.CONTENT_DIRECTORY);
return getResolver().query(rawContactUri, null, null, null);
}
allows to fetch contact's data inside application with appropriate authority regardless was it deleted by 3d-party application or not.
is there a column in the database of contacts indicates the date added to the base or the last modification date, because I want a method used to retrieve the new add
I found SEVERAL method but I did not understand, I am new to android
Edit : Means how to get the newly updated contacts.
you want to retrieve the number of new contacts since when?
if you adding contacts with your app then just get the number of contacts before you add any and save that value.
then after the user has added contacts get the number again and find the difference between the previous number of contacts. that will be the number of new contacts, but the best way to do it would just be to keep an internal counter of when the user adds contacts.
I think you are looking for something like this, You want to get the updated contacts.
have look here....
Contacts ContentObserver called randomly
Android notify when phone book is updated(Content Observer)
ContentObserver for listening contact changes
Just make this change to your cursor query
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, "_id DESC");
i did a lot of research but couldn't find anything to help;
my problem is: i need to create an application where the user can select some of the contacts on his phone to be added to this application where he/she can later communicate with them via sms in a special template. but the user need to select only one phone number to be active to this user on this application. this choice must be caved for later logons.
i was able to retrieve contacts and their phone numbers using lookupkey (which will be saved in my application as a reference for preselected users), but i couldn't figure out how to tag the needed phone number, i was thinking of adding a flag to the phone number but i dont know how, i dont know if this is the right way to do it, i thought of setting the selected phone number as primary then query t when needed... or simply save the phone number id (but i am not sure if saving the id is safe in case user changed the phone numer)...
thx for any help...
After a long period of trial and error I found the solution to my problem. I will be using the contacts lookup key to store the contact and the phone id to store the phone number...as follows:
String selection = ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY + " = '" + lookupkey+ "' and "+Phone._ID+"='"+phoneid+"'";
String[] projection =new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER};
Cursor managedCursor = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, null, Phone.DISPLAY_NAME + " ASC");
I'm a bit new to all this stuff. As I understand it, an id match is fast, but may not be stable. If a key+id match fails, you should also try a slower match using only the key - Jeffrey Scofield's SQL selection string could be changed to try id-and-key OR key-only (trusting the query optimiser to prioritize the id match).
I haven't had much luck finding information concerning the wisdom of storing the key long term.
I wrote a select query to access set of records from database by setting null for the argument 'orderBy' in the query(). I found that order of records returned by query() method when I run the application in mobile is completely different when I run the same sample application in tablet.
My Query:
Cursor cursor = database.query(true, tableName, downloadQueueTableColumnNames, selection, null, null, null, null, null);
Here, in the query orderBy field is null.
I hope someone to explain the reason behind this...
If you aren't ordering the results, they can be returned in any order. The same device doesn't have to give the same order if you call it twice in a row. If you want it in the same order every time, you must use an order by.
I'm trying to figure out if there is a property in Android contacts that states if a contact has been modified.
I read that it was possible to read a contact's version via the field ContactsContract.Contacts.Entity.VERSION, but I wasn't able to retrieve its value. I always get an IllegalArgumentException.
Does someone know how to get the contact's version or if there is another way to find out if a contact has been modified since the last scanning of the address book?
Heres the code, I havent tested it, as I was busy with my work.
public void getVersion() {
//specify which fields of RawContacts table to be retrieved.
String[] projection = new String[] {RawContacts.VERSION};
//query the RawContacts.CONTENT_URI
Cursor cur = mContext.getContentResolver().query(RawContacts.CONTENT_URI, projection,null,null,null);
while(cur.moveToNext()){
String version = cur.getString(cur.getColumnIndex(RawContacts.VERSION));
Log.i("VersionRetriever", version);
}
//Always remember to close the cursor. Otherwise it leads to side-effects.
cur.close();
}
try RawContacts.CONTACT_STATUS_TIMESTAMP instead of RawContacts.VERSION.
If you want to know if a specific data type (like phone or name), was changed you can check Data.DATA_VERSION (but on Data.CONTENT_URI).