Get contact per account type - android

Can somebody help me on how to get all contacts per account? Meaning, I want to put a condition which will determine if the contact is from the phone (created by user) or from google and some other sync sources because as of now I was getting all contacts and its the combination of all sync sources e.g. local contacts, google or even yahoo contacts ?

Can somebody help me on how to get all contacts per account?
You can use next snippet to retrieve contacts for a particular account type:
String where = RawContacts.ACCOUNT_TYPE+ "=?";
String[] args = { accountType };
Cursor contacts = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, where, args, null);
int numberIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int displayNameIndex = contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
for (contacts.moveToFirst(); !contacts.isAfterLast(); contacts.moveToNext()) {
String number = contacts.getString(numberIndex);
String displayName = contacts.getString(displayNameIndex);
// do something with account contacts
}
contacts.close();
To filter plain phone contacts (not connected to any account) you can use:
String where = RawContacts.ACCOUNT_TYPE+ " IS NULL";

Related

Does the ContactsContract.Contacts._ID remains?

I access the contacts list this way:
CursorLoader oCursorLoader = new CursorLoader(MyContext, ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
Cursor oCursor = oCursorLoader.loadInBackground();
int contactId = oCursor.getColumnIndex(ContactsContract.Contacts._ID);
int name = oCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
oCursor.moveToFirst();
if(oCursor.isAfterLast()==false) {
do {
String sId = oCursor.getString(contactId);
String phName = oCursor.getString(name);
...more code...
} while (oCursor.moveToNext());
}
I want to save the ID for a contact in a database to do some processing later on. For example, I want to save latest contacts called.
My question is:
Does the ID for a contact remains the same even if the contact is modified?
For example, if I save in the database the id "44" por user "Boss", does that ID remains the same even if the device is rebooted, or contact is modified (for example its name or phone number or email address)?

Unable to retrieve SMS display name

I've been trying to retrieve SMS information but have only been to retrieve everything BUT the display name of contacts. strDisplayNameonly shows the numerical value of a particular contact and not the name itself. All other string version of data shows their corresponding information correctly (aside from "date"). I've tried other implementations of getting the display name from other answers, but doing so causes the app to crash when trying to test.
Uri smsData = Uri.parse("content://sms/" + folderName);
String[] id = new String[]
{
"_id", "person", "address",
"body", "date"
};
ContentResolver contentResolver = getContentResolver();
Cursor smsCursor = contentResolver.query(smsData, null, null, null, null);
// Retrieve index of data
int indexContactID = smsCursor.getColumnIndex(id[0]);
int indexDisplayName = smsCursor.getColumnIndex(id[1]);
int indexPhoneNumber = smsCursor.getColumnIndex(id[2]);
int indexMsg = smsCursor.getColumnIndex(id[3]);
int indexDate = smsCursor.getColumnIndex(id[4]);
if (indexMsg < 0 || !smsCursor.moveToFirst())
return;
mCustomAdapter.clear();
while (smsCursor.moveToNext())
{
// Retrieve string version of data
String strContactID = smsCursor.getString(indexContactID);
String strDisplayName = smsCursor.getString(indexDisplayName);
String strContactNumber = smsCursor.getString(indexPhoneNumber);
String strMsg = smsCursor.getString(indexMsg);
String strDate = smsCursor.getString(indexDate);
String[] textMessage = new String[]
{
strContactID, strDisplayName, strContactNumber,
strMsg, strDate
};
// Place collected data into custom adapter
mCustomAdapter.add(textMessage);
}
smsCursor.close();
Who told you "person" is the contact's display-name?
According to the docs:
PERSON
The ID of the sender of the conversation, if present.
This is actually a "sender-id" this is never a contact-id, as an sms can be sent from a contact, a non-contact phone number, a non-phone-number (like GOOGLE or FACEBOOK) and from a group containing two or more of the above types.
If you'd like to get check if this is a contact, and if it is, get the contact's name, you need to pass two steps:
Use the canonical-address table to translate between id and phone-number (address). You can copy and use Android's helper class for this RecipientIdCache
In case the address is a single phone number, use the PHONE_LOOKUP table to look for a contact with that number, this will help: https://stackoverflow.com/a/7967182/819355

Syncing android contacts with server

I am creating an android app that keeps track of all contacts saved on the device (the ones that appear in the default android contacts app) and saves them in a MySQL table on the server.
I managed to read all contact data using ContectResolver:
//to read only android address book
String where = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.HAS_PHONE_NUMBER};
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, where, null, null);
Then, using the ContactsContract.Contacts._ID I query additional contact data:
// Perform a query to retrieve the contact's name parts
String[] nameProjection = new String[] {
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
};
Cursor nameCursor = cr.query(
ContactsContract.Data.CONTENT_URI,
nameProjection,
ContactsContract.Data.MIMETYPE + " = '" +
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "' AND " +
ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID
+ " = ?", new String[] { id }, null);
// Retrieve the name parts
String firstName = "", middleName = "", lastName = "", displayName = "";
if(nameCursor.moveToNext()) {
firstName = nameCursor.getString(nameCursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
middleName = nameCursor.getString(nameCursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
lastName = nameCursor.getString(nameCursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
displayName = nameCursor.getString(nameCursor.getColumnIndex(
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
}
I then send all this data (including the contact's email addresses and phone numbers) to the server.
I want to be able to periodically backup the device's contacts like this, but to be able to detect changes in contact data, by comparing the old data to the new data. But to do this, i need to have some sort of link between the contacts in the android device, and my DB in which i save the contact data.
After some searching i found 3 options:
ContactsContract.Contacts._ID
ContactsContract.Contacts.LOOKUP_KEY
ContactsContract.RawContacts._ID
But from what I found, all of them are not reliable, and can change in certain situations - invalidating the link between my DB to the device's contact list.
I have considered the option to use ContentObserver to detect contact changes. But, I want to be able to detect contact changes even if my app has been uninstalled, then some contacts have changed and then my app has been reinstalled.
Is there a reliable identification key per contact that I can use, to know when a certain contact has been changed or deleted?
EDIT:
I now found this variable exists: ContactsContract.ContactsColumns.CONTACT_LAST_UPDATED_TIMESTAMP
The problem is that it was introduces only in API level 18. I am working on min API 15. Is there something that could replace it for the missing API levels?
I am afraid it is not possible to know if particular contact changed. Therefore you can register observer on whole address book URI. This way you will be able to listen when anything in address book changes.
Now having observer you can scan all contacts and perform "sync" data to your server.
In your particular case pair of ContactsContract.Contacts._ID and ContactsContract.Contacts.LOOKUP_KEY should be reliable enough. But in order to know if anything changed you need either:
send all contacts to server and perform sync logic on server (id and lookup key should be stored on MySQL)
keep local copy of contacts on your device (sqllite db, realm, any other storage) in order to avoid unchanged contacts to be sent to server every time you sync

Android retrieve contact within Company to suggest like Gmail

I am new to Android, currently I can retrieve contact list and image from Google contact. However, the contact list from my App does not provide suggestion for email within my company like the Google Gmail app.
Is it possible that I can retrieve these extra email addresses?
Below is the code to retrieve contact
public ArrayList<String> getNameEmailDetails() {
ArrayList<String> emlRecs = new ArrayList<String>();
HashSet<String> emlRecsHS = new HashSet<String>();
ContentResolver cr = getContentResolver();
String[] PROJECTION = new String[] { ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Photo.CONTACT_ID };
String order = "CASE WHEN "
+ ContactsContract.Contacts.DISPLAY_NAME
+ " NOT LIKE '%#%' THEN 1 ELSE 2 END, "
+ ContactsContract.Contacts.DISPLAY_NAME
+ ", "
+ ContactsContract.CommonDataKinds.Email.DATA
+ " COLLATE NOCASE";
String filter = ContactsContract.CommonDataKinds.Email.DATA + " NOT LIKE ''";
Cursor cur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, filter, null, order);
if (cur.moveToFirst()) {
do {
// names comes in hand sometimes
String name = cur.getString(1);
String email = cur.getString(3);
String contact_id = cur.getString(4);
Bitmap profilePic = openPhoto(Long.parseLong(contact_id));
if (profilePic != null) {
profileList.add(new WordMatchAdapterWithIMG.profileWithIMG(email, profilePic));
}
} while (cur.moveToNext());
}
cur.close();
return emlRecs;
}
I would suggest you use the Google Contacts API.
The Google Contacts API allows client applications to view and update a user's contacts. Contacts are stored in the user's Google Account; most Google services have access to the contact list.
To retrieve a single contact, send an authorized GET request to the contact's selfLink URL:
https://www.google.com/m8/feeds/contacts/{userEmail}/full/{contactId}
Upon success, the server responds with an HTTP 200 OK status code and the requested contact entry.
public static ContactEntry retrieveContact(ContactsService myService) {
ContactEntry contact =
myService.getEntry(new URL("https://www.google.com/m8/feeds/contacts/default/full/contactId"),
ContactEntry.class);
// Do something with the contact.
return contact;
}
Useful Materials
Fetch Google/Gmail contacts using Google Contacts API and OAuth2 in Android
PHP GMAIL Contacts XML Parsing with DOMDocument and cURL

How to get contacts associated with social media(google,yahoo,...) synced with phone, in android

My issue is, when I'm fetching contacts from phone, it will get all the contacts (from phone, SIM, social accounts etc)
i want to know, if I can get contacts from social accounts separately?
As long as the contacts for the applications are synced, you can query the RawContacts (with the READ_CONTACTS permission in your manifest) and get them filtered by account type. For example:
Cursor c = getContentResolver().query(
RawContacts.CONTENT_URI,
new String[] { RawContacts.CONTACT_ID, RawContacts.DISPLAY_NAME_PRIMARY },
RawContacts.ACCOUNT_TYPE + "= ?",
new String[] { <account type here> },
null);
ArrayList<String> myContacts = new ArrayList<String>();
int contactNameColumn = c.getColumnIndex(RawContacts.DISPLAY_NAME_PRIMARY);
while (c.moveToNext())
{
// You can also read RawContacts.CONTACT_ID to read the
// ContactsContract.Contacts table or any of the other related ones.
myContacts.add(c.getString(contactNameColumn));
}
It's just a matter of supplying the appropriate account type. For example:
"com.google" for Gmail,
"com.whatsapp" for WhatsApp,
"com.skype.contacts.sync" for Skype,
&c.

Categories

Resources