I can get contact id and name from my contact list. But LAST_TIME_CONTACTED returns 0. How can I get LAST_TIME_CONTACTED correctly ?
My code:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0)
{
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String last = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED));
}
}
By the looks of things this isn't properly implemented by all device manufacturers. As such it seems like an unreliable field to use unfortunately. Almost certainly the case if you're using a Samsung Galaxy device...
As a side note, I think it's stored as an integer so you might be better using getInt() but I doubt very much that that's the problem.
Like Ed Hinchliffe said, it seems to be an unreliable field. However, you might be able to store such a value yourself if that is acceptable for your use case.
If you use a BroadcastReceiver and a PhoneStateListener you might be able to pull it off.
You would simply need to use String.valueOf(currentDate.getTime()); and store the value somewhere.
Related
I am working on a requirement, where I need to identify all Google's contact saved/synced with Android device's phonebook. Then I have to fetch unique contact Id (Google's unique contact id)of each contact which will be same on other devices and other platform.
I have read Android developer's documentation regarding RAW_CONTACT_ID. Also, tried to get raw contact id, but I am getting different value of raw contact id on other devices.
If anyone can put me on right direction, it will really helpful.
If require more information, please ask.
Try using ContactsContract.PhoneLookup
A table that represents the result of looking up a phone number, for example for caller ID. To perform a lookup you must append the number you want to find to CONTENT_FILTER_URI. This query is highly optimized.
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME,...
where
PhoneLookup._ID
is what you're looking for.
You may also try the solution provided in this post:
public static int getContactIDFromNumber(String contactNumber,Context context)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = new Random().nextInt();
Cursor contactLookupCursor = context.getContentResolver().query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,contactNumber),new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext()){
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
All _ID values in Android's Contacts are local, they are usually incremental, and are not synced between devices.
The values that might get synced by the app's SyncAdapter (in this case Google's SyncAdapter) are SYNC1, SYNC2, SYNC3, SYNC4.
However, note that these fields are not guaranteed to do anything, and the SyncAdapter may use them for whatever purpose it needs, usually, one of them is used as a "server identifier" you just need to print them, and check manually which one.
I started building my app for api 13, because I thougth it could be efficient enough for the most users.
But i changed it to api 10.
Then the following code stopped working `
String empName=data.getStringExtra("name");
String hourPay=data.getStringExtra("hourPay");
String key="";
String id="";
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, empName);
Cursor idCursor = getContentResolver().query(lookupUri, null, null, null, null);
idCursor.moveToFirst();
id = idCursor.getString(idCursor.getColumnIndex(ContactsContract.Contacts._ID));
key = idCursor.getString(idCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));`
The problem is that it works only with contact names written in English or the ones that have just name (not surname)
For example :
It works for the following contacts :
Express Service,
George,
Maria Mpakou,
Σοφια,
With no distinction between languages
But when a contact is written in my language (greek) and has space (e.g Αιμιλιος Δημιος) it returns the underneath cursor with index out of bounds.
When i first tried at api 13 worked like a charm.
By the way my Android.Manifest has utf-8 encoding if that has something to do with it
Please any recomendation will bw helpfull.
Thanks
After a lot of search i finally did it with a different way...like asking a Sql query to all contacts
Here is the code:
String empName=data.getStringExtra("name");
Cursor idCursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,null,Contacts.DISPLAY_NAME+" = '"+empName+"'", null, null);
That worked like a charm!
I am a little bit confuse about the how to use Data.HAS_PHONE_NUMBER.
I have inserted contacts along with some additional Data and I would like to retrieve some of those contacts.
If I'm running the following code eveything is fine:
Uri uri = Data.CONTENT_URI;
String[] projection = new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME };
String selection = Data.DATA4+" = ?";
String[] selectionArgs = new String[] {MY_VALUE};
Cursor truContactCursor = mContext.getContentResolver().query(uri, projection, selection, selectionArgs, null);
Now, I would like to know if those contacts have a phone number so I added HAS_PHONE_NUMBER into the projection like this:
String[] projection = new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME, Data.HAS_PHONE_NUMBER };
When running the query I got the following execption:
java.lang.IllegalArgumentException: Invalid column has_phone_number
Why can I not access to HAS_PHONE_NUMBER? There is no problem with Data.DISPLAY_NAME which is in the same table. How are we suppose to use Data.HAS_PHONE_NUMBER then?
Thanks for your answer
Use HAS_PHONE_NUMBER is used for checking whether an contact has at least one phone number.example:
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.getCount()>0){
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));id
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if(cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))>0){
//Query phone here.
}
or add in projection:
String [] projection = {ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER};
Add "Data.MIMETYPE=ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE" to the selection statement.
The result cursor will include only the rows which have a phone number.
Tip.
There is the case: several numbers in one contact.
If you want all the numbers to be queried, add "ContactsContract.Data.DATA1" (Which means phone number) to the projection statement.
I encountered this same problem, and the only other reference to the problem I have found is another stackoverflow question.
I am planning on writing my own ContentProvider to do the "join" through programmatic means. That is, do the original query against the Data.CONTENT_URI but without the Data.HAS_PHONE_NUMBER projection, and then requery the given contact for the actual value of Data.HAS_PHONE_NUMBER. This surely lacks the performance of an actual DB join (being an n+1-type of select), but will provide the desired/expected functionality. This extra processing could be made conditional upon the OS level in order to maintain the efficiency on correctly functioning OS versions.
Given yulistic's answer above and my own experience, it would appear to be a bug in some versions of Android that this implicit join is not done. My Android v2.3.7 phone crashes with the same error you receive when Data.HAS_PHONE_NUMBER is in the projection, whereas my Android v4.2.2 tablet does not crash.
I have entered an Android Bug against the issue:
https://code.google.com/p/android/issues/detail?id=54095
Rob
I have the following problem:
I have a RawContactID and want to get every information about this contact. I run a query like this:
String selection = ContactsContract.RawContactsEntity.RAW_CONTACT_ID +" = ?";
String[] selectionArgs = new String[]{contacts[0].get(0)};
Cursor cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, selection, selectionArgs, null);
After that I run the cursor through a lot of elseif-Statemens to distinguish betweene the different MIME-Types and read the informations. Works fine, besides that it is very much code only to read informations about one contact, but ok.
The problem is that the MIME-Type for Mobilephonenumber and Telephonenumber are the same (vnd.android.cursor.item/phone_v2)??
How can i distinguish between those to different informations?
Any hint is highly appreciated!
ContactsContract.CommonDataKinds.Phone will let you distinguish between the types. There is a long list of which TYPE_HOME and TYPE_MOBILE are just two.
The sdk reference also states
You can use all columns defined for ContactsContract.Data as well as the following aliases.
I am trying to read the contact list using the following code:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(People.CONTENT_URI,null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(People._ID));
Cursor personCur = cr.query(Contacts.Phones.CONTENT_URI,
null,
Contacts.Phones.PERSON_ID +"= ?"+ Contacts.Phones.NUMBER_KEY ,
new String[]{id}, null);
String phoneKey = "";
while (personCur.moveToNext()) {
phoneKey = personCur.getString(personCur.getColumnIndex(Contacts.Phones.NUMBER_KEY));
}
The problem is that phoneKey return in reverse order meaning if the phone number is 054-123-4567 the value is 7654321450
I could not find any documentation on this issue.
Any idea how to fix it? or is it the expected result?
thanks
-Z
Firstly, Contacts.Phones.NUMBER_KEY is deprecated.
Secondly, why do you need this value? This is not the phone number, but the "normalized" phone number.
If you want the phone number in the way you have your code, use Contacts.Phones.NUMBER
Anyways, I would suggest you not to use deprecated elements unless you are targeting older phones.
================
Phone numbers are stored in stripped reversed order for easier matching. It helps to use the LIKE operator in SQL.
For a normal SQL user, it might look same to use where NUMBER_KEY LIKE '%1234' and where NUMBER_KEY LIKE '4321%'.
But for the db engine, having the wildcard at the end is much easier (efficient) Efficiency is a major factor for incoming call caller id lookup.
BTW, you might have not noticed, most phones (not talking about android only) does not match the whole number for caller id lookup.
In all my Nokia phones I have a number saved, say its 016 12345678 (its not the real number) as Mr X
When I get phone call from another number 016 99345678, it shows Mr X is calling. It compares only last few digits!!!