package fr.neamar.kiss.dataprovider;
import android.database.ContentObserver;
import android.provider.ContactsContract;
import java.util.ArrayList;
import java.util.regex.Pattern;
import fr.neamar.kiss.loader.LoadContactsPojos;
import fr.neamar.kiss.normalizer.PhoneNormalizer;
import fr.neamar.kiss.normalizer.StringNormalizer;
import fr.neamar.kiss.pojo.ContactsPojo;
import fr.neamar.kiss.pojo.Pojo;
public class ContactsProvider extends Provider<ContactsPojo> {
private ContentObserver cObserver = new ContentObserver(null) {
@Override
public void onChange(boolean selfChange) {
//reload contacts
reload();
}
};
@Override
public void reload() {
this.initialize(new LoadContactsPojos(this));
}
@Override
public void onCreate() {
super.onCreate();
//register content observer
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, cObserver);
}
@Override
public void onDestroy() {
super.onDestroy();
//deregister content observer
getContentResolver().unregisterContentObserver(cObserver);
}
public ArrayList<Pojo> getResults(String query) {
query = StringNormalizer.normalize(query);
ArrayList<Pojo> results = new ArrayList<>();
// Search people with composed names, e.g "jean-marie"
// (not part of the StringNormalizer class, since we want to keep dashes on other providers)
query = query.replaceAll("-", " ");
int relevance;
int matchPositionStart;
int matchPositionEnd;
String contactNameNormalized;
final String queryWithSpace = " " + query;
for (ContactsPojo contact : pojos) {
relevance = 0;
contactNameNormalized = contact.nameNormalized;
boolean alias = false;
matchPositionStart = 0;
matchPositionEnd = 0;
if (contactNameNormalized.startsWith(query)) {
relevance = 50;
matchPositionEnd = matchPositionStart + query.length();
} else if ((matchPositionStart = contactNameNormalized.indexOf(queryWithSpace)) > -1) {
relevance = 40;
matchPositionEnd = matchPositionStart + queryWithSpace.length();
} else if (contact.nickname.contains(query)) {
alias = true;
contact.displayName = contact.name
+ " <small>("
+ contact.nickname.replaceFirst(
"(?i)(" + Pattern.quote(query) + ")", "{$1}")
+ ")</small>";
relevance = 30;
} else if (query.length() > 2) {
matchPositionStart = 0;
matchPositionEnd = 0;
if (contact.phoneSimplified.startsWith(query)) {
relevance = 10;
} else if (contact.phoneSimplified.contains(query)) {
relevance = 5;
}
}
if (relevance > 0) {
// Increase relevance according to number of times the contacts
// was phoned :
relevance += contact.timesContacted;
// Increase relevance for starred contacts:
if (contact.starred)
relevance += 30;
// Decrease for home numbers:
if (contact.homeNumber)
relevance -= 1;
if (!alias)
contact.setDisplayNameHighlightRegion(matchPositionStart, matchPositionEnd);
contact.relevance = relevance;
results.add(contact);
// Circuit-breaker to avoid spending too much time
// building results
// Important: this is made possible because LoadContactsPojos already
// returns contacts sorted by popularity, so the first items should be the most useful ones.
// (short queries, e.g. "a" with thousands of contacts,
// can return hundreds of results which are then slow to sort and display)
if (results.size() > 50) {
break;
}
}
}
return results;
}
public Pojo findById(String id) {
for (Pojo pojo : pojos) {
if (pojo.id.equals(id)) {
pojo.displayName = pojo.name;
return pojo;
}
}
return null;
}
public Pojo findByName(String name) {
for (Pojo pojo : pojos) {
if (pojo.name.equals(name))
return pojo;
}
return null;
}
/**
* Find a ContactsPojo from a phoneNumber
* If many contacts match, the one most often contacted will be returned
*
* @param phoneNumber phone number to find (will be normalized)
* @return a contactpojo, or null.
*/
public ContactsPojo findByPhone(String phoneNumber) {
String simplifiedPhoneNumber = PhoneNormalizer.simplifyPhoneNumber(phoneNumber);
for (ContactsPojo pojo : pojos) {
if (pojo.phoneSimplified.equals(simplifiedPhoneNumber)) {
return pojo;
}
}
return null;
}
}